From 9a33599428af279f237eba111307110dc889f4f3 Mon Sep 17 00:00:00 2001 From: Daniel_M_Williams Date: Sun, 23 Feb 2020 08:54:22 -0500 Subject: [PATCH] [Retire Android Client] Due to lack of interest, the Android client is being retired. --- .../ActionBarSherlock/.classpath | 9 - android-libraries/ActionBarSherlock/.project | 33 - .../ActionBarSherlock/AndroidManifest.xml | 6 - .../com/actionbarsherlock/BuildConfig.java | 6 - .../gen/com/actionbarsherlock/R.java | 2813 ----------------- .../libs/android-support-v4.jar | Bin 271788 -> 0 bytes .../ActionBarSherlock/proguard-project.txt | 20 - .../ActionBarSherlock/project.properties | 12 - ...s__primary_text_disable_only_holo_dark.xml | 20 - ...__primary_text_disable_only_holo_light.xml | 21 - .../res/color/abs__primary_text_holo_dark.xml | 24 - .../color/abs__primary_text_holo_light.xml | 26 - .../abs__ab_bottom_solid_dark_holo.9.png | Bin 144 -> 0 bytes .../abs__ab_bottom_solid_inverse_holo.9.png | Bin 138 -> 0 bytes .../abs__ab_bottom_solid_light_holo.9.png | Bin 144 -> 0 bytes ...abs__ab_bottom_transparent_dark_holo.9.png | Bin 135 -> 0 bytes ...bs__ab_bottom_transparent_light_holo.9.png | Bin 134 -> 0 bytes .../abs__ab_share_pack_holo_dark.9.png | Bin 2866 -> 0 bytes .../abs__ab_share_pack_holo_light.9.png | Bin 2862 -> 0 bytes .../abs__ab_solid_dark_holo.9.png | Bin 146 -> 0 bytes .../abs__ab_solid_light_holo.9.png | Bin 145 -> 0 bytes .../abs__ab_solid_shadow_holo.9.png | Bin 192 -> 0 bytes .../abs__ab_stacked_solid_dark_holo.9.png | Bin 146 -> 0 bytes .../abs__ab_stacked_solid_light_holo.9.png | Bin 146 -> 0 bytes ...bs__ab_stacked_transparent_dark_holo.9.png | Bin 139 -> 0 bytes ...s__ab_stacked_transparent_light_holo.9.png | Bin 133 -> 0 bytes .../abs__ab_transparent_dark_holo.9.png | Bin 155 -> 0 bytes .../abs__ab_transparent_light_holo.9.png | Bin 145 -> 0 bytes .../abs__btn_cab_done_default_holo_dark.9.png | Bin 104 -> 0 bytes ...abs__btn_cab_done_default_holo_light.9.png | Bin 102 -> 0 bytes .../abs__btn_cab_done_focused_holo_dark.9.png | Bin 112 -> 0 bytes ...abs__btn_cab_done_focused_holo_light.9.png | Bin 108 -> 0 bytes .../abs__btn_cab_done_pressed_holo_dark.9.png | Bin 110 -> 0 bytes ...abs__btn_cab_done_pressed_holo_light.9.png | Bin 108 -> 0 bytes ...abs__cab_background_bottom_holo_dark.9.png | Bin 149 -> 0 bytes ...bs__cab_background_bottom_holo_light.9.png | Bin 145 -> 0 bytes .../abs__cab_background_top_holo_dark.9.png | Bin 147 -> 0 bytes .../abs__cab_background_top_holo_light.9.png | Bin 147 -> 0 bytes .../abs__dialog_full_holo_dark.9.png | Bin 1414 -> 0 bytes .../abs__dialog_full_holo_light.9.png | Bin 1537 -> 0 bytes .../abs__ic_ab_back_holo_dark.png | Bin 602 -> 0 bytes .../abs__ic_ab_back_holo_light.png | Bin 546 -> 0 bytes .../abs__ic_cab_done_holo_dark.png | Bin 713 -> 0 bytes .../abs__ic_cab_done_holo_light.png | Bin 737 -> 0 bytes ..._ic_menu_moreoverflow_normal_holo_dark.png | Bin 144 -> 0 bytes ...ic_menu_moreoverflow_normal_holo_light.png | Bin 148 -> 0 bytes .../abs__ic_menu_share_holo_dark.png | Bin 467 -> 0 bytes .../abs__ic_menu_share_holo_light.png | Bin 505 -> 0 bytes .../abs__list_activated_holo.9.png | Bin 154 -> 0 bytes .../abs__list_divider_holo_dark.9.png | Bin 78 -> 0 bytes .../abs__list_divider_holo_light.9.png | Bin 76 -> 0 bytes .../abs__list_focused_holo.9.png | Bin 159 -> 0 bytes .../abs__list_longpressed_holo.9.png | Bin 154 -> 0 bytes .../abs__list_pressed_holo_dark.9.png | Bin 159 -> 0 bytes .../abs__list_pressed_holo_light.9.png | Bin 159 -> 0 bytes ...bs__list_selector_disabled_holo_dark.9.png | Bin 189 -> 0 bytes ...s__list_selector_disabled_holo_light.9.png | Bin 189 -> 0 bytes .../abs__menu_dropdown_panel_holo_dark.9.png | Bin 922 -> 0 bytes .../abs__menu_dropdown_panel_holo_light.9.png | Bin 1061 -> 0 bytes .../abs__progress_bg_holo_dark.9.png | Bin 178 -> 0 bytes .../abs__progress_bg_holo_light.9.png | Bin 174 -> 0 bytes .../abs__progress_primary_holo_dark.9.png | Bin 917 -> 0 bytes .../abs__progress_primary_holo_light.9.png | Bin 917 -> 0 bytes .../abs__progress_secondary_holo_dark.9.png | Bin 188 -> 0 bytes .../abs__progress_secondary_holo_light.9.png | Bin 188 -> 0 bytes .../abs__spinner_48_inner_holo.png | Bin 2081 -> 0 bytes .../abs__spinner_48_outer_holo.png | Bin 1811 -> 0 bytes .../abs__spinner_ab_default_holo_dark.9.png | Bin 311 -> 0 bytes .../abs__spinner_ab_default_holo_light.9.png | Bin 312 -> 0 bytes .../abs__spinner_ab_disabled_holo_dark.9.png | Bin 306 -> 0 bytes .../abs__spinner_ab_disabled_holo_light.9.png | Bin 306 -> 0 bytes .../abs__spinner_ab_focused_holo_dark.9.png | Bin 524 -> 0 bytes .../abs__spinner_ab_focused_holo_light.9.png | Bin 523 -> 0 bytes .../abs__spinner_ab_pressed_holo_dark.9.png | Bin 464 -> 0 bytes .../abs__spinner_ab_pressed_holo_light.9.png | Bin 458 -> 0 bytes .../abs__tab_selected_focused_holo.9.png | Bin 147 -> 0 bytes .../abs__tab_selected_holo.9.png | Bin 148 -> 0 bytes .../abs__tab_selected_pressed_holo.9.png | Bin 147 -> 0 bytes .../abs__tab_unselected_pressed_holo.9.png | Bin 145 -> 0 bytes .../res/drawable-hdpi/ic_launcher.png | Bin 9397 -> 0 bytes .../res/drawable-ldpi/ic_launcher.png | Bin 2729 -> 0 bytes .../abs__ab_bottom_solid_dark_holo.9.png | Bin 134 -> 0 bytes .../abs__ab_bottom_solid_inverse_holo.9.png | Bin 129 -> 0 bytes .../abs__ab_bottom_solid_light_holo.9.png | Bin 134 -> 0 bytes ...abs__ab_bottom_transparent_dark_holo.9.png | Bin 123 -> 0 bytes ...bs__ab_bottom_transparent_light_holo.9.png | Bin 123 -> 0 bytes .../abs__ab_share_pack_holo_dark.9.png | Bin 2851 -> 0 bytes .../abs__ab_share_pack_holo_light.9.png | Bin 122 -> 0 bytes .../abs__ab_solid_dark_holo.9.png | Bin 133 -> 0 bytes .../abs__ab_solid_light_holo.9.png | Bin 133 -> 0 bytes .../abs__ab_solid_shadow_holo.9.png | Bin 168 -> 0 bytes .../abs__ab_stacked_solid_dark_holo.9.png | Bin 134 -> 0 bytes .../abs__ab_stacked_solid_light_holo.9.png | Bin 133 -> 0 bytes ...bs__ab_stacked_transparent_dark_holo.9.png | Bin 127 -> 0 bytes ...s__ab_stacked_transparent_light_holo.9.png | Bin 123 -> 0 bytes .../abs__ab_transparent_dark_holo.9.png | Bin 139 -> 0 bytes .../abs__ab_transparent_light_holo.9.png | Bin 133 -> 0 bytes .../abs__btn_cab_done_default_holo_dark.9.png | Bin 101 -> 0 bytes ...abs__btn_cab_done_default_holo_light.9.png | Bin 99 -> 0 bytes .../abs__btn_cab_done_focused_holo_dark.9.png | Bin 109 -> 0 bytes ...abs__btn_cab_done_focused_holo_light.9.png | Bin 105 -> 0 bytes .../abs__btn_cab_done_pressed_holo_dark.9.png | Bin 107 -> 0 bytes ...abs__btn_cab_done_pressed_holo_light.9.png | Bin 105 -> 0 bytes ...abs__cab_background_bottom_holo_dark.9.png | Bin 127 -> 0 bytes ...bs__cab_background_bottom_holo_light.9.png | Bin 124 -> 0 bytes .../abs__cab_background_top_holo_dark.9.png | Bin 130 -> 0 bytes .../abs__cab_background_top_holo_light.9.png | Bin 128 -> 0 bytes .../abs__dialog_full_holo_dark.9.png | Bin 882 -> 0 bytes .../abs__dialog_full_holo_light.9.png | Bin 1003 -> 0 bytes .../abs__ic_ab_back_holo_dark.png | Bin 466 -> 0 bytes .../abs__ic_ab_back_holo_light.png | Bin 438 -> 0 bytes .../abs__ic_cab_done_holo_dark.png | Bin 566 -> 0 bytes .../abs__ic_cab_done_holo_light.png | Bin 552 -> 0 bytes ..._ic_menu_moreoverflow_normal_holo_dark.png | Bin 122 -> 0 bytes ...ic_menu_moreoverflow_normal_holo_light.png | Bin 131 -> 0 bytes .../abs__ic_menu_share_holo_dark.png | Bin 332 -> 0 bytes .../abs__ic_menu_share_holo_light.png | Bin 355 -> 0 bytes .../abs__list_activated_holo.9.png | Bin 151 -> 0 bytes .../abs__list_divider_holo_dark.9.png | Bin 78 -> 0 bytes .../abs__list_divider_holo_light.9.png | Bin 76 -> 0 bytes .../abs__list_focused_holo.9.png | Bin 158 -> 0 bytes .../abs__list_longpressed_holo.9.png | Bin 151 -> 0 bytes .../abs__list_pressed_holo_dark.9.png | Bin 158 -> 0 bytes .../abs__list_pressed_holo_light.9.png | Bin 158 -> 0 bytes ...bs__list_selector_disabled_holo_dark.9.png | Bin 172 -> 0 bytes ...s__list_selector_disabled_holo_light.9.png | Bin 171 -> 0 bytes .../abs__menu_dropdown_panel_holo_dark.9.png | Bin 651 -> 0 bytes .../abs__menu_dropdown_panel_holo_light.9.png | Bin 720 -> 0 bytes .../abs__progress_bg_holo_dark.9.png | Bin 165 -> 0 bytes .../abs__progress_bg_holo_light.9.png | Bin 159 -> 0 bytes .../abs__progress_primary_holo_dark.9.png | Bin 572 -> 0 bytes .../abs__progress_primary_holo_light.9.png | Bin 572 -> 0 bytes .../abs__progress_secondary_holo_dark.9.png | Bin 170 -> 0 bytes .../abs__progress_secondary_holo_light.9.png | Bin 170 -> 0 bytes .../abs__spinner_48_inner_holo.png | Bin 1336 -> 0 bytes .../abs__spinner_48_outer_holo.png | Bin 1165 -> 0 bytes .../abs__spinner_ab_default_holo_dark.9.png | Bin 254 -> 0 bytes .../abs__spinner_ab_default_holo_light.9.png | Bin 255 -> 0 bytes .../abs__spinner_ab_disabled_holo_dark.9.png | Bin 249 -> 0 bytes .../abs__spinner_ab_disabled_holo_light.9.png | Bin 249 -> 0 bytes .../abs__spinner_ab_focused_holo_dark.9.png | Bin 417 -> 0 bytes .../abs__spinner_ab_focused_holo_light.9.png | Bin 424 -> 0 bytes .../abs__spinner_ab_pressed_holo_dark.9.png | Bin 370 -> 0 bytes .../abs__spinner_ab_pressed_holo_light.9.png | Bin 370 -> 0 bytes .../abs__tab_selected_focused_holo.9.png | Bin 148 -> 0 bytes .../abs__tab_selected_holo.9.png | Bin 151 -> 0 bytes .../abs__tab_selected_pressed_holo.9.png | Bin 150 -> 0 bytes .../abs__tab_unselected_pressed_holo.9.png | Bin 155 -> 0 bytes .../res/drawable-mdpi/ic_launcher.png | Bin 5237 -> 0 bytes .../abs__progress_medium_holo.xml | 34 - .../abs__ab_bottom_solid_dark_holo.9.png | Bin 165 -> 0 bytes .../abs__ab_bottom_solid_inverse_holo.9.png | Bin 157 -> 0 bytes .../abs__ab_bottom_solid_light_holo.9.png | Bin 166 -> 0 bytes ...abs__ab_bottom_transparent_dark_holo.9.png | Bin 153 -> 0 bytes ...bs__ab_bottom_transparent_light_holo.9.png | Bin 152 -> 0 bytes .../abs__ab_share_pack_holo_dark.9.png | Bin 2875 -> 0 bytes .../abs__ab_share_pack_holo_light.9.png | Bin 2869 -> 0 bytes .../abs__ab_solid_dark_holo.9.png | Bin 163 -> 0 bytes .../abs__ab_solid_light_holo.9.png | Bin 163 -> 0 bytes .../abs__ab_solid_shadow_holo.9.png | Bin 290 -> 0 bytes .../abs__ab_stacked_solid_dark_holo.9.png | Bin 163 -> 0 bytes .../abs__ab_stacked_solid_light_holo.9.png | Bin 163 -> 0 bytes ...bs__ab_stacked_transparent_dark_holo.9.png | Bin 158 -> 0 bytes ...s__ab_stacked_transparent_light_holo.9.png | Bin 152 -> 0 bytes .../abs__ab_transparent_dark_holo.9.png | Bin 171 -> 0 bytes .../abs__ab_transparent_light_holo.9.png | Bin 160 -> 0 bytes .../abs__btn_cab_done_default_holo_dark.9.png | Bin 109 -> 0 bytes ...abs__btn_cab_done_default_holo_light.9.png | Bin 108 -> 0 bytes .../abs__btn_cab_done_focused_holo_dark.9.png | Bin 112 -> 0 bytes ...abs__btn_cab_done_focused_holo_light.9.png | Bin 113 -> 0 bytes .../abs__btn_cab_done_pressed_holo_dark.9.png | Bin 115 -> 0 bytes ...abs__btn_cab_done_pressed_holo_light.9.png | Bin 113 -> 0 bytes ...abs__cab_background_bottom_holo_dark.9.png | Bin 166 -> 0 bytes ...bs__cab_background_bottom_holo_light.9.png | Bin 161 -> 0 bytes .../abs__cab_background_top_holo_dark.9.png | Bin 174 -> 0 bytes .../abs__cab_background_top_holo_light.9.png | Bin 161 -> 0 bytes .../abs__dialog_full_holo_dark.9.png | Bin 2159 -> 0 bytes .../abs__dialog_full_holo_light.9.png | Bin 2302 -> 0 bytes .../abs__ic_ab_back_holo_dark.png | Bin 741 -> 0 bytes .../abs__ic_ab_back_holo_light.png | Bin 661 -> 0 bytes .../abs__ic_cab_done_holo_dark.png | Bin 970 -> 0 bytes .../abs__ic_cab_done_holo_light.png | Bin 915 -> 0 bytes ..._ic_menu_moreoverflow_normal_holo_dark.png | Bin 167 -> 0 bytes ...ic_menu_moreoverflow_normal_holo_light.png | Bin 184 -> 0 bytes .../abs__ic_menu_share_holo_dark.png | Bin 699 -> 0 bytes .../abs__ic_menu_share_holo_light.png | Bin 935 -> 0 bytes .../abs__list_activated_holo.9.png | Bin 158 -> 0 bytes .../abs__list_divider_holo_dark.9.png | Bin 83 -> 0 bytes .../abs__list_divider_holo_light.9.png | Bin 83 -> 0 bytes .../abs__list_focused_holo.9.png | Bin 163 -> 0 bytes .../abs__list_longpressed_holo.9.png | Bin 158 -> 0 bytes .../abs__list_pressed_holo_dark.9.png | Bin 163 -> 0 bytes .../abs__list_pressed_holo_light.9.png | Bin 163 -> 0 bytes ...bs__list_selector_disabled_holo_dark.9.png | Bin 190 -> 0 bytes ...s__list_selector_disabled_holo_light.9.png | Bin 188 -> 0 bytes .../abs__menu_dropdown_panel_holo_dark.9.png | Bin 1362 -> 0 bytes .../abs__menu_dropdown_panel_holo_light.9.png | Bin 1551 -> 0 bytes .../abs__progress_bg_holo_dark.9.png | Bin 174 -> 0 bytes .../abs__progress_bg_holo_light.9.png | Bin 172 -> 0 bytes .../abs__progress_primary_holo_dark.9.png | Bin 1309 -> 0 bytes .../abs__progress_primary_holo_light.9.png | Bin 1309 -> 0 bytes .../abs__progress_secondary_holo_dark.9.png | Bin 184 -> 0 bytes .../abs__progress_secondary_holo_light.9.png | Bin 184 -> 0 bytes .../abs__spinner_48_inner_holo.png | Bin 2769 -> 0 bytes .../abs__spinner_48_outer_holo.png | Bin 2432 -> 0 bytes .../abs__spinner_ab_default_holo_dark.9.png | Bin 395 -> 0 bytes .../abs__spinner_ab_default_holo_light.9.png | Bin 394 -> 0 bytes .../abs__spinner_ab_disabled_holo_dark.9.png | Bin 381 -> 0 bytes .../abs__spinner_ab_disabled_holo_light.9.png | Bin 381 -> 0 bytes .../abs__spinner_ab_focused_holo_dark.9.png | Bin 680 -> 0 bytes .../abs__spinner_ab_focused_holo_light.9.png | Bin 671 -> 0 bytes .../abs__spinner_ab_pressed_holo_dark.9.png | Bin 609 -> 0 bytes .../abs__spinner_ab_pressed_holo_light.9.png | Bin 602 -> 0 bytes .../abs__tab_selected_focused_holo.9.png | Bin 147 -> 0 bytes .../abs__tab_selected_holo.9.png | Bin 153 -> 0 bytes .../abs__tab_selected_pressed_holo.9.png | Bin 147 -> 0 bytes .../abs__tab_unselected_pressed_holo.9.png | Bin 149 -> 0 bytes .../res/drawable-xhdpi/ic_launcher.png | Bin 14383 -> 0 bytes .../abs__activated_background_holo_dark.xml | 20 - .../abs__activated_background_holo_light.xml | 20 - .../drawable/abs__btn_cab_done_holo_dark.xml | 24 - .../drawable/abs__btn_cab_done_holo_light.xml | 24 - .../abs__ic_menu_moreoverflow_holo_dark.xml | 18 - .../abs__ic_menu_moreoverflow_holo_light.xml | 18 - .../abs__item_background_holo_dark.xml | 26 - .../abs__item_background_holo_light.xml | 26 - ...lector_background_transition_holo_dark.xml | 20 - ...ector_background_transition_holo_light.xml | 20 - .../drawable/abs__list_selector_holo_dark.xml | 27 - .../abs__list_selector_holo_light.xml | 28 - .../abs__progress_horizontal_holo_dark.xml | 32 - .../abs__progress_horizontal_holo_light.xml | 32 - .../drawable/abs__progress_medium_holo.xml | 34 - .../drawable/abs__spinner_ab_holo_dark.xml | 25 - .../drawable/abs__spinner_ab_holo_light.xml | 25 - .../drawable/abs__tab_indicator_ab_holo.xml | 34 - .../abs__action_mode_close_item.xml | 40 - .../sherlock_spinner_dropdown_item.xml | 26 - .../res/layout-v14/sherlock_spinner_item.xml | 26 - .../layout-xlarge/abs__screen_action_bar.xml | 50 - .../abs__screen_action_bar_overlay.xml | 49 - .../res/layout/abs__action_bar_home.xml | 38 - .../res/layout/abs__action_bar_tab.xml | 7 - .../layout/abs__action_bar_tab_bar_view.xml | 6 - .../res/layout/abs__action_bar_title_item.xml | 50 - .../layout/abs__action_menu_item_layout.xml | 56 - .../res/layout/abs__action_menu_layout.xml | 23 - .../res/layout/abs__action_mode_bar.xml | 24 - .../layout/abs__action_mode_close_item.xml | 31 - .../res/layout/abs__activity_chooser_view.xml | 70 - .../abs__activity_chooser_view_list_item.xml | 53 - .../res/layout/abs__dialog_title_holo.xml | 46 - .../layout/abs__list_menu_item_checkbox.xml | 26 - .../res/layout/abs__list_menu_item_icon.xml | 28 - .../res/layout/abs__list_menu_item_layout.xml | 59 - .../res/layout/abs__list_menu_item_radio.xml | 24 - .../layout/abs__popup_menu_item_layout.xml | 60 - .../res/layout/abs__screen_action_bar.xml | 57 - .../layout/abs__screen_action_bar_overlay.xml | 59 - .../res/layout/abs__screen_simple.xml | 38 - ...abs__screen_simple_overlay_action_mode.xml | 38 - .../ActionBarSherlock/res/layout/main.xml | 12 - .../layout/sherlock_spinner_dropdown_item.xml | 26 - .../res/layout/sherlock_spinner_item.xml | 26 - .../res/values-land/abs__dimens.xml | 33 - .../abs__dimens.xml | 33 - .../abs__dimens.xml | 33 - .../abs__dimens.xml | 33 - .../abs__dimens.xml | 36 - .../res/values-large/abs__dimens.xml | 29 - .../res/values-sw600dp/abs__bools.xml | 19 - .../res/values-sw600dp/abs__dimens.xml | 38 - .../res/values-v11/abs__themes.xml | 12 - .../res/values-v14/abs__styles.xml | 118 - .../res/values-v14/abs__themes.xml | 32 - .../res/values-w360dp/abs__dimens.xml | 22 - .../res/values-w480dp/abs__bools.xml | 22 - .../res/values-w480dp/abs__config.xml | 29 - .../res/values-w500dp/abs__dimens.xml | 22 - .../res/values-w600dp/abs__dimens.xml | 22 - .../res/values-xlarge/abs__dimens.xml | 45 - .../res/values/abs__attrs.xml | 380 --- .../res/values/abs__bools.xml | 22 - .../res/values/abs__colors.xml | 27 - .../res/values/abs__config.xml | 43 - .../res/values/abs__dimens.xml | 50 - .../ActionBarSherlock/res/values/abs__ids.xml | 26 - .../res/values/abs__strings.xml | 42 - .../res/values/abs__styles.xml | 384 --- .../res/values/abs__themes.xml | 226 -- .../ActionBarSherlock/res/values/strings.xml | 7 - .../v4/app/_ActionBarSherlockTrojanHorse.java | 144 - .../actionbarsherlock/ActionBarSherlock.java | 791 ----- .../com/actionbarsherlock/app/ActionBar.java | 947 ------ .../app/SherlockActivity.java | 259 -- .../app/SherlockDialogFragment.java | 68 - .../app/SherlockExpandableListActivity.java | 259 -- .../app/SherlockFragment.java | 68 - .../app/SherlockFragmentActivity.java | 292 -- .../app/SherlockListActivity.java | 259 -- .../app/SherlockListFragment.java | 68 - .../app/SherlockPreferenceActivity.java | 259 -- .../internal/ActionBarSherlockCompat.java | 1207 ------- .../internal/ActionBarSherlockNative.java | 328 -- .../internal/ResourcesCompat.java | 95 - .../internal/app/ActionBarImpl.java | 1026 ------ .../internal/app/ActionBarWrapper.java | 468 --- .../nineoldandroids/animation/Animator.java | 278 -- .../animation/AnimatorListenerAdapter.java | 54 - .../animation/AnimatorSet.java | 1111 ------- .../animation/FloatEvaluator.java | 42 - .../animation/FloatKeyframeSet.java | 136 - .../animation/IntEvaluator.java | 42 - .../animation/IntKeyframeSet.java | 135 - .../nineoldandroids/animation/Keyframe.java | 361 --- .../animation/KeyframeSet.java | 227 -- .../animation/ObjectAnimator.java | 491 --- .../animation/PropertyValuesHolder.java | 1012 ------ .../animation/TypeEvaluator.java | 44 - .../animation/ValueAnimator.java | 1265 -------- .../nineoldandroids/view/NineViewGroup.java | 79 - .../view/animation/AnimatorProxy.java | 212 -- .../widget/NineFrameLayout.java | 65 - .../widget/NineHorizontalScrollView.java | 41 - .../widget/NineLinearLayout.java | 65 - .../internal/view/ActionProviderWrapper.java | 40 - .../internal/view/StandaloneActionMode.java | 148 - .../view/View_HasStateListenerSupport.java | 6 - .../View_OnAttachStateChangeListener.java | 8 - .../internal/view/menu/ActionMenu.java | 264 -- .../internal/view/menu/ActionMenuItem.java | 278 -- .../view/menu/ActionMenuItemView.java | 295 -- .../view/menu/ActionMenuPresenter.java | 721 ----- .../internal/view/menu/ActionMenuView.java | 572 ---- .../internal/view/menu/BaseMenuPresenter.java | 231 -- .../internal/view/menu/ListMenuItemView.java | 278 -- .../internal/view/menu/MenuBuilder.java | 1335 -------- .../internal/view/menu/MenuItemImpl.java | 647 ---- .../internal/view/menu/MenuItemWrapper.java | 292 -- .../internal/view/menu/MenuPopupHelper.java | 376 --- .../internal/view/menu/MenuPresenter.java | 148 - .../internal/view/menu/MenuView.java | 120 - .../internal/view/menu/MenuWrapper.java | 180 -- .../internal/view/menu/SubMenuBuilder.java | 134 - .../internal/view/menu/SubMenuWrapper.java | 72 - .../internal/widget/AbsActionBarView.java | 291 -- .../internal/widget/ActionBarContainer.java | 245 -- .../internal/widget/ActionBarContextView.java | 518 --- .../internal/widget/ActionBarView.java | 1548 --------- .../internal/widget/CapitalizingButton.java | 40 - .../internal/widget/CapitalizingTextView.java | 44 - .../widget/FakeDialogPhoneWindow.java | 64 - .../internal/widget/IcsAbsSpinner.java | 479 --- .../internal/widget/IcsAdapterView.java | 1160 ------- .../internal/widget/IcsLinearLayout.java | 272 -- .../internal/widget/IcsListPopupWindow.java | 644 ---- .../internal/widget/IcsProgressBar.java | 1193 ------- .../internal/widget/IcsSpinner.java | 703 ---- .../internal/widget/IcsView.java | 21 - .../widget/ScrollingTabContainerView.java | 545 ---- .../actionbarsherlock/view/ActionMode.java | 224 -- .../view/ActionProvider.java | 170 - .../view/CollapsibleActionView.java | 39 - .../src/com/actionbarsherlock/view/Menu.java | 447 --- .../actionbarsherlock/view/MenuInflater.java | 472 --- .../com/actionbarsherlock/view/MenuItem.java | 598 ---- .../com/actionbarsherlock/view/SubMenu.java | 110 - .../com/actionbarsherlock/view/Window.java | 65 - .../widget/ActivityChooserModel.java | 1131 ------- .../widget/ActivityChooserView.java | 818 ----- .../widget/ShareActionProvider.java | 316 -- android-libraries/TreeViewList/.classpath | 8 - android-libraries/TreeViewList/.project | 33 - .../TreeViewList/AndroidManifest.xml | 11 - .../gen/pl/polidea/treeview/BuildConfig.java | 6 - .../gen/pl/polidea/treeview/R.java | 276 -- android-libraries/TreeViewList/proguard.cfg | 40 - .../TreeViewList/project.properties | 12 - .../res/drawable-hdpi/collapsed.png | Bin 455 -> 0 bytes .../res/drawable-hdpi/expanded.png | Bin 361 -> 0 bytes .../res/drawable-hdpi/ic_launcher.png | Bin 4147 -> 0 bytes .../res/drawable-ldpi/collapsed.png | Bin 313 -> 0 bytes .../res/drawable-ldpi/expanded.png | Bin 291 -> 0 bytes .../res/drawable-ldpi/ic_launcher.png | Bin 1723 -> 0 bytes .../res/drawable-mdpi/collapsed.png | Bin 272 -> 0 bytes .../res/drawable-mdpi/expanded.png | Bin 254 -> 0 bytes .../res/drawable-mdpi/ic_launcher.png | Bin 2574 -> 0 bytes .../TreeViewList/res/drawable/divider.xml | 6 - .../res/drawable/list_selector_background.xml | 45 - .../list_selector_background_disabled.9.png | Bin 1252 -> 0 bytes .../list_selector_background_focus.9.png | Bin 11006 -> 0 bytes .../list_selector_background_longpress.9.png | Bin 3017 -> 0 bytes .../list_selector_background_pressed.9.png | Bin 11006 -> 0 bytes .../list_selector_background_transition.xml | 20 - .../res/layout/tree_list_item_wrapper.xml | 13 - .../TreeViewList/res/values/attrs.xml | 42 - .../TreeViewList/res/values/styles.xml | 7 - .../treeview/AbstractTreeViewAdapter.java | 315 -- .../pl/polidea/treeview/InMemoryTreeNode.java | 116 - .../treeview/InMemoryTreeStateManager.java | 374 --- .../treeview/NodeAlreadyInTreeException.java | 14 - .../treeview/NodeNotInTreeException.java | 15 - .../src/pl/polidea/treeview/TreeBuilder.java | 126 - .../treeview/TreeConfigurationException.java | 15 - .../src/pl/polidea/treeview/TreeNodeInfo.java | 69 - .../pl/polidea/treeview/TreeStateManager.java | 193 -- .../src/pl/polidea/treeview/TreeViewList.java | 198 -- .../src/pl/polidea/treeview/overview.html | 24 - .../src/pl/polidea/treeview/package-info.java | 4 - android-libraries/achartengine/.classpath | 8 - android-libraries/achartengine/.project | 33 - .../achartengine/AndroidManifest.xml | 8 - .../achartengine/extra/LICENSE-2.0.txt | 202 -- .../achartengine/project.properties | 12 - .../src/org/achartengine/ChartFactory.java | 708 ----- .../org/achartengine/GraphicalActivity.java | 48 - .../src/org/achartengine/GraphicalView.java | 337 -- .../src/org/achartengine/ITouchHandler.java | 63 - .../src/org/achartengine/TouchHandler.java | 204 -- .../src/org/achartengine/TouchHandlerOld.java | 137 - .../org/achartengine/chart/AbstractChart.java | 475 --- .../src/org/achartengine/chart/BarChart.java | 329 -- .../org/achartengine/chart/BubbleChart.java | 146 - .../org/achartengine/chart/ClickableArea.java | 44 - .../achartengine/chart/CombinedXYChart.java | 177 -- .../achartengine/chart/CubicLineChart.java | 120 - .../src/org/achartengine/chart/DialChart.java | 236 -- .../org/achartengine/chart/DoughnutChart.java | 162 - .../src/org/achartengine/chart/LineChart.java | 175 - .../src/org/achartengine/chart/PieChart.java | 136 - .../src/org/achartengine/chart/PieMapper.java | 139 - .../org/achartengine/chart/PieSegment.java | 70 - .../org/achartengine/chart/PointStyle.java | 90 - .../org/achartengine/chart/RangeBarChart.java | 145 - .../chart/RangeStackedBarChart.java | 29 - .../org/achartengine/chart/RoundChart.java | 143 - .../org/achartengine/chart/ScatterChart.java | 266 -- .../src/org/achartengine/chart/TimeChart.java | 226 -- .../src/org/achartengine/chart/XYChart.java | 905 ------ .../src/org/achartengine/chart/package.html | 6 - .../src/org/achartengine/image/zoom-1.png | Bin 1139 -> 0 bytes .../src/org/achartengine/image/zoom_in.png | Bin 1099 -> 0 bytes .../src/org/achartengine/image/zoom_out.png | Bin 1074 -> 0 bytes .../achartengine/model/CategorySeries.java | 143 - .../model/MultipleCategorySeries.java | 145 - .../src/org/achartengine/model/Point.java | 52 - .../model/RangeCategorySeries.java | 111 - .../achartengine/model/SeriesSelection.java | 49 - .../org/achartengine/model/TimeSeries.java | 43 - .../model/XYMultipleSeriesDataset.java | 94 - .../src/org/achartengine/model/XYSeries.java | 255 -- .../org/achartengine/model/XYValueSeries.java | 139 - .../src/org/achartengine/model/package.html | 6 - .../src/org/achartengine/package.html | 6 - .../achartengine/renderer/BasicStroke.java | 107 - .../renderer/DefaultRenderer.java | 750 ----- .../achartengine/renderer/DialRenderer.java | 196 -- .../renderer/SimpleSeriesRenderer.java | 235 -- .../renderer/XYMultipleSeriesRenderer.java | 1101 ------- .../renderer/XYSeriesRenderer.java | 128 - .../org/achartengine/renderer/package.html | 6 - .../org/achartengine/tools/AbstractTool.java | 111 - .../src/org/achartengine/tools/FitZoom.java | 78 - .../src/org/achartengine/tools/Pan.java | 163 - .../org/achartengine/tools/PanListener.java | 28 - .../src/org/achartengine/tools/Zoom.java | 189 -- .../src/org/achartengine/tools/ZoomEvent.java | 56 - .../org/achartengine/tools/ZoomListener.java | 33 - .../src/org/achartengine/util/IndexXYMap.java | 108 - .../src/org/achartengine/util/MathHelper.java | 174 - .../src/org/achartengine/util/XYEntry.java | 45 - .../src/org/achartengine/util/package.html | 6 - android/.classpath | 11 - android/.project | 45 - android/AndroidManifest.xml | 87 - android/libs/android-support-v4.jar | Bin 271788 -> 0 bytes android/lint.xml | 3 - android/proguard.cfg | 40 - android/project.properties | 14 - .../res/drawable-hdpi/arrow_down_float.png | Bin 618 -> 0 bytes android/res/drawable-hdpi/arrow_up_float.png | Bin 616 -> 0 bytes android/res/drawable-hdpi/ic_menu_add.png | Bin 2194 -> 0 bytes android/res/drawable-hdpi/ic_menu_archive.png | Bin 1094 -> 0 bytes .../res/drawable-hdpi/ic_menu_download.png | Bin 909 -> 0 bytes .../drawable-hdpi/ic_menu_info_details.png | Bin 1983 -> 0 bytes .../res/drawable-hdpi/ic_menu_preferences.png | Bin 1851 -> 0 bytes android/res/drawable-hdpi/ic_menu_save.png | Bin 1248 -> 0 bytes android/res/drawable-hdpi/or_launcher.png | Bin 9575 -> 0 bytes .../res/drawable-ldpi/arrow_down_float.png | Bin 424 -> 0 bytes android/res/drawable-ldpi/arrow_up_float.png | Bin 422 -> 0 bytes android/res/drawable-ldpi/ic_menu_add.png | Bin 1580 -> 0 bytes android/res/drawable-ldpi/ic_menu_archive.png | Bin 1140 -> 0 bytes .../drawable-ldpi/ic_menu_info_details.png | Bin 1499 -> 0 bytes .../res/drawable-ldpi/ic_menu_preferences.png | Bin 1601 -> 0 bytes android/res/drawable-ldpi/ic_menu_save.png | Bin 1279 -> 0 bytes android/res/drawable-ldpi/or_launcher.png | Bin 3114 -> 0 bytes .../res/drawable-mdpi/arrow_down_float.png | Bin 3141 -> 0 bytes android/res/drawable-mdpi/arrow_up_float.png | Bin 3128 -> 0 bytes android/res/drawable-mdpi/ic_directory.png | Bin 1354 -> 0 bytes android/res/drawable-mdpi/ic_menu_add.png | Bin 1339 -> 0 bytes android/res/drawable-mdpi/ic_menu_archive.png | Bin 831 -> 0 bytes .../drawable-mdpi/ic_menu_info_details.png | Bin 1237 -> 0 bytes .../res/drawable-mdpi/ic_menu_preferences.png | Bin 1142 -> 0 bytes android/res/drawable-mdpi/ic_menu_save.png | Bin 981 -> 0 bytes android/res/drawable-mdpi/ic_motorbrowser.png | Bin 2725 -> 0 bytes android/res/drawable-mdpi/ic_star_select.png | Bin 964 -> 0 bytes .../res/drawable-mdpi/ic_star_unselected.png | Bin 993 -> 0 bytes android/res/drawable-mdpi/or_launcher.png | Bin 4941 -> 0 bytes android/res/drawable-xhdpi/ic_menu_add.png | Bin 3061 -> 0 bytes .../res/drawable-xhdpi/ic_menu_archive.png | Bin 1398 -> 0 bytes .../res/drawable-xhdpi/ic_menu_download.png | Bin 1167 -> 0 bytes .../drawable-xhdpi/ic_menu_info_details.png | Bin 2763 -> 0 bytes .../drawable-xhdpi/ic_menu_preferences.png | Bin 2507 -> 0 bytes android/res/drawable-xhdpi/ic_menu_save.png | Bin 1546 -> 0 bytes android/res/drawable-xhdpi/or_launcher.png | Bin 16057 -> 0 bytes android/res/drawable/filebrowser_home.xml | 7 - android/res/drawable/openrocket.png | Bin 22753 -> 0 bytes android/res/drawable/rocketglobe.png | Bin 123979 -> 0 bytes android/res/drawable/sf_donate.png | Bin 8378 -> 0 bytes android/res/drawable/simulation_state.xml | 8 - .../res/drawable/simulation_state_green.xml | 9 - android/res/drawable/simulation_state_red.xml | 9 - .../res/drawable/simulation_state_yellow.xml | 9 - android/res/drawable/starfield.png | Bin 65403 -> 0 bytes android/res/layout-land/main.xml | 62 - .../res/layout-land/simulation_event_item.xml | 37 - .../res/layout-large-land/motorbrowser.xml | 20 - .../layout-large-land/openrocketviewer.xml | 26 - .../res/layout-xlarge-port/motorbrowser.xml | 19 - .../layout-xlarge-port/openrocketviewer.xml | 26 - android/res/layout/component_list_item.xml | 18 - android/res/layout/filebrowser_list_item.xml | 30 - android/res/layout/main.xml | 58 - .../res/layout/motor_config_delay_dialog.xml | 26 - android/res/layout/motor_config_item.xml | 46 - android/res/layout/motor_detail_form.xml | 127 - android/res/layout/motor_list_child.xml | 74 - android/res/layout/motor_list_dialog.xml | 13 - android/res/layout/motor_list_group.xml | 18 - android/res/layout/motorbrowser.xml | 12 - android/res/layout/openrocketviewer.xml | 18 - android/res/layout/rocket_component.xml | 7 - android/res/layout/rocket_configurations.xml | 17 - android/res/layout/rocket_overview.xml | 123 - android/res/layout/rocket_simulations.xml | 12 - android/res/layout/simplefilebrowser.xml | 18 - .../layout/simulation_condition_dialog.xml | 91 - .../res/layout/simulation_event_dialog.xml | 13 - android/res/layout/simulation_event_item.xml | 40 - .../res/layout/simulation_graph_activity.xml | 17 - android/res/layout/simulation_list_item.xml | 35 - .../layout/simulation_plot_config_dialog.xml | 42 - ...simulation_plot_config_event_list_item.xml | 11 - android/res/layout/tcqueryform.xml | 67 - android/res/menu/main_menu.xml | 16 - .../res/menu/motor_browser_option_menu.xml | 19 - ...cket_viewer_configurations_option_menu.xml | 11 - .../res/menu/rocket_viewer_option_menu.xml | 34 - .../rocket_viewer_simulation_option_menu.xml | 11 - android/res/menu/simulation_option_menu.xml | 10 - android/res/values-fr/strings.xml | 105 - android/res/values-v11/styles.xml | 22 - android/res/values/pref_strings.xml | 120 - android/res/values/simulation_states.xml | 9 - android/res/values/strings.xml | 115 - android/res/values/styles.xml | 33 - android/res/xml/preferences.xml | 76 - android/src/build.properties | 2 - .../android/AboutDialogFragment.java | 46 - .../openrocket/android/ActivityHelpers.java | 45 - .../sf/openrocket/android/Application.java | 69 - .../sf/openrocket/android/CurrentRocket.java | 154 - .../android/CurrentRocketHolder.java | 12 - .../src/net/sf/openrocket/android/Main.java | 72 - .../android/MotorDatabaseAdapter.java | 44 - .../android/PreferencesActivity.java | 106 - .../android/PreferencesAdapter.java | 105 - .../android/db/ConversionUtils.java | 115 - .../sf/openrocket/android/db/DbAdapter.java | 81 - .../sf/openrocket/android/db/MotorDao.java | 280 -- .../events/ChangeEventBroadcastReceiver.java | 44 - .../sf/openrocket/android/events/Events.java | 14 - .../filebrowser/AlphanumComparator.java | 138 - .../filebrowser/SimpleFileBrowser.java | 288 -- .../android/motor/BurnPlotActivity.java | 23 - .../android/motor/BurnPlotFragment.java | 158 - .../motor/ExtendedThrustCurveMotor.java | 53 - .../android/motor/MotorBrowserActivity.java | 129 - .../motor/MotorDelayDialogFragment.java | 112 - .../android/motor/MotorDetailsFragment.java | 104 - .../motor/MotorListDialogFragment.java | 157 - .../android/motor/MotorListFragment.java | 249 -- .../openrocket/android/rocket/Component.java | 75 - .../android/rocket/Configurations.java | 336 -- .../ErrorLoadingFileDialogFragment.java | 59 - .../rocket/MissingMotorDialogFragment.java | 80 - .../android/rocket/MissingMotorHelpers.java | 76 - .../android/rocket/MotorConfigSpinner.java | 87 - .../rocket/OpenRocketLoaderActivity.java | 249 -- .../rocket/OpenRocketLoaderFragment.java | 122 - .../rocket/OpenRocketLoaderResult.java | 13 - .../rocket/OpenRocketSaverFragment.java | 126 - .../android/rocket/OpenRocketViewer.java | 303 -- .../openrocket/android/rocket/Overview.java | 147 - .../rocket/RocketComponentTreeAdapter.java | 72 - .../android/rocket/WarningDialogFragment.java | 42 - .../android/simservice/SimulationService.java | 96 - .../android/simservice/SimulationTask.java | 13 - .../android/simulation/SimulationChart.java | 282 -- .../simulation/SimulationEditFragment.java | 132 - .../simulation/SimulationEventsDialog.java | 78 - .../simulation/SimulationListItem.java | 91 - .../SimulationPlotConfigDialog.java | 166 - .../simulation/SimulationViewActivity.java | 59 - .../simulation/SimulationViewFragment.java | 97 - .../android/simulation/Simulations.java | 175 - .../android/thrustcurve/Base64Decoder.java | 122 - .../android/thrustcurve/DownloadRequest.java | 43 - .../android/thrustcurve/DownloadResponse.java | 41 - .../thrustcurve/DownloadResponseParser.java | 121 - .../android/thrustcurve/MotorBurnFile.java | 84 - .../android/thrustcurve/SearchRequest.java | 117 - .../android/thrustcurve/SearchResponse.java | 45 - .../thrustcurve/SearchResponseParser.java | 281 -- .../thrustcurve/SupportedFileTypes.java | 11 - .../TCMissingMotorDownloadAction.java | 104 - .../android/thrustcurve/TCMotor.java | 299 -- .../android/thrustcurve/TCQueryAction.java | 156 - .../android/thrustcurve/TCQueryActivity.java | 73 - .../android/thrustcurve/TCSearchAction.java | 75 - .../android/thrustcurve/ThrustCurveAPI.java | 152 - .../android/util/AndroidLogWrapper.java | 134 - .../android/util/ErrorDialogFragment.java | 40 - .../android/util/ExpandableListFragment.java | 351 -- .../PersistentExpandableListFragment.java | 112 - .../util/PersistentExpandableListView.java | 89 - .../android/util/ProgressDialogFragment.java | 46 - 637 files changed, 59146 deletions(-) delete mode 100644 android-libraries/ActionBarSherlock/.classpath delete mode 100644 android-libraries/ActionBarSherlock/.project delete mode 100644 android-libraries/ActionBarSherlock/AndroidManifest.xml delete mode 100644 android-libraries/ActionBarSherlock/gen/com/actionbarsherlock/BuildConfig.java delete mode 100644 android-libraries/ActionBarSherlock/gen/com/actionbarsherlock/R.java delete mode 100644 android-libraries/ActionBarSherlock/libs/android-support-v4.jar delete mode 100644 android-libraries/ActionBarSherlock/proguard-project.txt delete mode 100644 android-libraries/ActionBarSherlock/project.properties delete mode 100644 android-libraries/ActionBarSherlock/res/color/abs__primary_text_disable_only_holo_dark.xml delete mode 100644 android-libraries/ActionBarSherlock/res/color/abs__primary_text_disable_only_holo_light.xml delete mode 100644 android-libraries/ActionBarSherlock/res/color/abs__primary_text_holo_dark.xml delete mode 100644 android-libraries/ActionBarSherlock/res/color/abs__primary_text_holo_light.xml delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ab_bottom_solid_dark_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ab_bottom_solid_inverse_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ab_bottom_solid_light_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ab_bottom_transparent_dark_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ab_bottom_transparent_light_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ab_share_pack_holo_dark.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ab_share_pack_holo_light.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ab_solid_dark_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ab_solid_light_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ab_solid_shadow_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ab_stacked_solid_dark_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ab_stacked_solid_light_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ab_stacked_transparent_dark_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ab_stacked_transparent_light_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ab_transparent_dark_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ab_transparent_light_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__btn_cab_done_default_holo_dark.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__btn_cab_done_default_holo_light.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__btn_cab_done_focused_holo_dark.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__btn_cab_done_focused_holo_light.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__btn_cab_done_pressed_holo_dark.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__btn_cab_done_pressed_holo_light.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__cab_background_bottom_holo_dark.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__cab_background_bottom_holo_light.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__cab_background_top_holo_dark.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__cab_background_top_holo_light.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__dialog_full_holo_dark.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__dialog_full_holo_light.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ic_ab_back_holo_dark.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ic_ab_back_holo_light.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ic_cab_done_holo_dark.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ic_cab_done_holo_light.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ic_menu_moreoverflow_normal_holo_dark.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ic_menu_moreoverflow_normal_holo_light.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ic_menu_share_holo_dark.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ic_menu_share_holo_light.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__list_activated_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__list_divider_holo_dark.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__list_divider_holo_light.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__list_focused_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__list_longpressed_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__list_pressed_holo_dark.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__list_pressed_holo_light.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__list_selector_disabled_holo_dark.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__list_selector_disabled_holo_light.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__menu_dropdown_panel_holo_dark.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__menu_dropdown_panel_holo_light.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__progress_bg_holo_dark.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__progress_bg_holo_light.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__progress_primary_holo_dark.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__progress_primary_holo_light.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__progress_secondary_holo_dark.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__progress_secondary_holo_light.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__spinner_48_inner_holo.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__spinner_48_outer_holo.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__spinner_ab_default_holo_dark.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__spinner_ab_default_holo_light.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__spinner_ab_disabled_holo_dark.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__spinner_ab_disabled_holo_light.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__spinner_ab_focused_holo_dark.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__spinner_ab_focused_holo_light.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__spinner_ab_pressed_holo_dark.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__spinner_ab_pressed_holo_light.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__tab_selected_focused_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__tab_selected_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__tab_selected_pressed_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__tab_unselected_pressed_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-hdpi/ic_launcher.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-ldpi/ic_launcher.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ab_bottom_solid_dark_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ab_bottom_solid_inverse_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ab_bottom_solid_light_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ab_bottom_transparent_dark_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ab_bottom_transparent_light_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ab_share_pack_holo_dark.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ab_share_pack_holo_light.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ab_solid_dark_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ab_solid_light_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ab_solid_shadow_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ab_stacked_solid_dark_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ab_stacked_solid_light_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ab_stacked_transparent_dark_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ab_stacked_transparent_light_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ab_transparent_dark_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ab_transparent_light_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__btn_cab_done_default_holo_dark.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__btn_cab_done_default_holo_light.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__btn_cab_done_focused_holo_dark.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__btn_cab_done_focused_holo_light.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__btn_cab_done_pressed_holo_dark.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__btn_cab_done_pressed_holo_light.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__cab_background_bottom_holo_dark.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__cab_background_bottom_holo_light.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__cab_background_top_holo_dark.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__cab_background_top_holo_light.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__dialog_full_holo_dark.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__dialog_full_holo_light.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ic_ab_back_holo_dark.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ic_ab_back_holo_light.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ic_cab_done_holo_dark.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ic_cab_done_holo_light.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ic_menu_moreoverflow_normal_holo_dark.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ic_menu_moreoverflow_normal_holo_light.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ic_menu_share_holo_dark.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ic_menu_share_holo_light.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__list_activated_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__list_divider_holo_dark.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__list_divider_holo_light.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__list_focused_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__list_longpressed_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__list_pressed_holo_dark.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__list_pressed_holo_light.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__list_selector_disabled_holo_dark.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__list_selector_disabled_holo_light.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__menu_dropdown_panel_holo_dark.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__menu_dropdown_panel_holo_light.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__progress_bg_holo_dark.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__progress_bg_holo_light.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__progress_primary_holo_dark.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__progress_primary_holo_light.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__progress_secondary_holo_dark.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__progress_secondary_holo_light.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__spinner_48_inner_holo.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__spinner_48_outer_holo.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__spinner_ab_default_holo_dark.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__spinner_ab_default_holo_light.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__spinner_ab_disabled_holo_dark.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__spinner_ab_disabled_holo_light.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__spinner_ab_focused_holo_dark.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__spinner_ab_focused_holo_light.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__spinner_ab_pressed_holo_dark.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__spinner_ab_pressed_holo_light.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__tab_selected_focused_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__tab_selected_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__tab_selected_pressed_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__tab_unselected_pressed_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-mdpi/ic_launcher.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-v11/abs__progress_medium_holo.xml delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ab_bottom_solid_dark_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ab_bottom_solid_inverse_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ab_bottom_solid_light_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ab_bottom_transparent_dark_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ab_bottom_transparent_light_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ab_share_pack_holo_dark.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ab_share_pack_holo_light.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ab_solid_dark_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ab_solid_light_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ab_solid_shadow_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ab_stacked_solid_dark_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ab_stacked_solid_light_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ab_stacked_transparent_dark_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ab_stacked_transparent_light_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ab_transparent_dark_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ab_transparent_light_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__btn_cab_done_default_holo_dark.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__btn_cab_done_default_holo_light.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__btn_cab_done_focused_holo_dark.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__btn_cab_done_focused_holo_light.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__btn_cab_done_pressed_holo_dark.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__btn_cab_done_pressed_holo_light.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__cab_background_bottom_holo_dark.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__cab_background_bottom_holo_light.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__cab_background_top_holo_dark.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__cab_background_top_holo_light.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__dialog_full_holo_dark.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__dialog_full_holo_light.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ic_ab_back_holo_dark.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ic_ab_back_holo_light.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ic_cab_done_holo_dark.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ic_cab_done_holo_light.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ic_menu_moreoverflow_normal_holo_dark.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ic_menu_moreoverflow_normal_holo_light.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ic_menu_share_holo_dark.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ic_menu_share_holo_light.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__list_activated_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__list_divider_holo_dark.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__list_divider_holo_light.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__list_focused_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__list_longpressed_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__list_pressed_holo_dark.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__list_pressed_holo_light.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__list_selector_disabled_holo_dark.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__list_selector_disabled_holo_light.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__menu_dropdown_panel_holo_dark.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__menu_dropdown_panel_holo_light.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__progress_bg_holo_dark.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__progress_bg_holo_light.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__progress_primary_holo_dark.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__progress_primary_holo_light.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__progress_secondary_holo_dark.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__progress_secondary_holo_light.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__spinner_48_inner_holo.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__spinner_48_outer_holo.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__spinner_ab_default_holo_dark.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__spinner_ab_default_holo_light.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__spinner_ab_disabled_holo_dark.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__spinner_ab_disabled_holo_light.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__spinner_ab_focused_holo_dark.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__spinner_ab_focused_holo_light.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__spinner_ab_pressed_holo_dark.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__spinner_ab_pressed_holo_light.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__tab_selected_focused_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__tab_selected_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__tab_selected_pressed_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__tab_unselected_pressed_holo.9.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable-xhdpi/ic_launcher.png delete mode 100644 android-libraries/ActionBarSherlock/res/drawable/abs__activated_background_holo_dark.xml delete mode 100644 android-libraries/ActionBarSherlock/res/drawable/abs__activated_background_holo_light.xml delete mode 100644 android-libraries/ActionBarSherlock/res/drawable/abs__btn_cab_done_holo_dark.xml delete mode 100644 android-libraries/ActionBarSherlock/res/drawable/abs__btn_cab_done_holo_light.xml delete mode 100644 android-libraries/ActionBarSherlock/res/drawable/abs__ic_menu_moreoverflow_holo_dark.xml delete mode 100644 android-libraries/ActionBarSherlock/res/drawable/abs__ic_menu_moreoverflow_holo_light.xml delete mode 100644 android-libraries/ActionBarSherlock/res/drawable/abs__item_background_holo_dark.xml delete mode 100644 android-libraries/ActionBarSherlock/res/drawable/abs__item_background_holo_light.xml delete mode 100644 android-libraries/ActionBarSherlock/res/drawable/abs__list_selector_background_transition_holo_dark.xml delete mode 100644 android-libraries/ActionBarSherlock/res/drawable/abs__list_selector_background_transition_holo_light.xml delete mode 100644 android-libraries/ActionBarSherlock/res/drawable/abs__list_selector_holo_dark.xml delete mode 100644 android-libraries/ActionBarSherlock/res/drawable/abs__list_selector_holo_light.xml delete mode 100644 android-libraries/ActionBarSherlock/res/drawable/abs__progress_horizontal_holo_dark.xml delete mode 100644 android-libraries/ActionBarSherlock/res/drawable/abs__progress_horizontal_holo_light.xml delete mode 100644 android-libraries/ActionBarSherlock/res/drawable/abs__progress_medium_holo.xml delete mode 100644 android-libraries/ActionBarSherlock/res/drawable/abs__spinner_ab_holo_dark.xml delete mode 100644 android-libraries/ActionBarSherlock/res/drawable/abs__spinner_ab_holo_light.xml delete mode 100644 android-libraries/ActionBarSherlock/res/drawable/abs__tab_indicator_ab_holo.xml delete mode 100644 android-libraries/ActionBarSherlock/res/layout-large/abs__action_mode_close_item.xml delete mode 100644 android-libraries/ActionBarSherlock/res/layout-v14/sherlock_spinner_dropdown_item.xml delete mode 100644 android-libraries/ActionBarSherlock/res/layout-v14/sherlock_spinner_item.xml delete mode 100644 android-libraries/ActionBarSherlock/res/layout-xlarge/abs__screen_action_bar.xml delete mode 100644 android-libraries/ActionBarSherlock/res/layout-xlarge/abs__screen_action_bar_overlay.xml delete mode 100644 android-libraries/ActionBarSherlock/res/layout/abs__action_bar_home.xml delete mode 100644 android-libraries/ActionBarSherlock/res/layout/abs__action_bar_tab.xml delete mode 100644 android-libraries/ActionBarSherlock/res/layout/abs__action_bar_tab_bar_view.xml delete mode 100644 android-libraries/ActionBarSherlock/res/layout/abs__action_bar_title_item.xml delete mode 100644 android-libraries/ActionBarSherlock/res/layout/abs__action_menu_item_layout.xml delete mode 100644 android-libraries/ActionBarSherlock/res/layout/abs__action_menu_layout.xml delete mode 100644 android-libraries/ActionBarSherlock/res/layout/abs__action_mode_bar.xml delete mode 100644 android-libraries/ActionBarSherlock/res/layout/abs__action_mode_close_item.xml delete mode 100644 android-libraries/ActionBarSherlock/res/layout/abs__activity_chooser_view.xml delete mode 100644 android-libraries/ActionBarSherlock/res/layout/abs__activity_chooser_view_list_item.xml delete mode 100644 android-libraries/ActionBarSherlock/res/layout/abs__dialog_title_holo.xml delete mode 100644 android-libraries/ActionBarSherlock/res/layout/abs__list_menu_item_checkbox.xml delete mode 100644 android-libraries/ActionBarSherlock/res/layout/abs__list_menu_item_icon.xml delete mode 100644 android-libraries/ActionBarSherlock/res/layout/abs__list_menu_item_layout.xml delete mode 100644 android-libraries/ActionBarSherlock/res/layout/abs__list_menu_item_radio.xml delete mode 100644 android-libraries/ActionBarSherlock/res/layout/abs__popup_menu_item_layout.xml delete mode 100644 android-libraries/ActionBarSherlock/res/layout/abs__screen_action_bar.xml delete mode 100644 android-libraries/ActionBarSherlock/res/layout/abs__screen_action_bar_overlay.xml delete mode 100644 android-libraries/ActionBarSherlock/res/layout/abs__screen_simple.xml delete mode 100644 android-libraries/ActionBarSherlock/res/layout/abs__screen_simple_overlay_action_mode.xml delete mode 100644 android-libraries/ActionBarSherlock/res/layout/main.xml delete mode 100644 android-libraries/ActionBarSherlock/res/layout/sherlock_spinner_dropdown_item.xml delete mode 100644 android-libraries/ActionBarSherlock/res/layout/sherlock_spinner_item.xml delete mode 100644 android-libraries/ActionBarSherlock/res/values-land/abs__dimens.xml delete mode 100644 android-libraries/ActionBarSherlock/res/values-large-hdpi-1024x600/abs__dimens.xml delete mode 100644 android-libraries/ActionBarSherlock/res/values-large-land-hdpi-1024x600/abs__dimens.xml delete mode 100644 android-libraries/ActionBarSherlock/res/values-large-land-mdpi-1024x600/abs__dimens.xml delete mode 100644 android-libraries/ActionBarSherlock/res/values-large-mdpi-1024x600/abs__dimens.xml delete mode 100644 android-libraries/ActionBarSherlock/res/values-large/abs__dimens.xml delete mode 100644 android-libraries/ActionBarSherlock/res/values-sw600dp/abs__bools.xml delete mode 100644 android-libraries/ActionBarSherlock/res/values-sw600dp/abs__dimens.xml delete mode 100644 android-libraries/ActionBarSherlock/res/values-v11/abs__themes.xml delete mode 100644 android-libraries/ActionBarSherlock/res/values-v14/abs__styles.xml delete mode 100644 android-libraries/ActionBarSherlock/res/values-v14/abs__themes.xml delete mode 100644 android-libraries/ActionBarSherlock/res/values-w360dp/abs__dimens.xml delete mode 100644 android-libraries/ActionBarSherlock/res/values-w480dp/abs__bools.xml delete mode 100644 android-libraries/ActionBarSherlock/res/values-w480dp/abs__config.xml delete mode 100644 android-libraries/ActionBarSherlock/res/values-w500dp/abs__dimens.xml delete mode 100644 android-libraries/ActionBarSherlock/res/values-w600dp/abs__dimens.xml delete mode 100644 android-libraries/ActionBarSherlock/res/values-xlarge/abs__dimens.xml delete mode 100644 android-libraries/ActionBarSherlock/res/values/abs__attrs.xml delete mode 100644 android-libraries/ActionBarSherlock/res/values/abs__bools.xml delete mode 100644 android-libraries/ActionBarSherlock/res/values/abs__colors.xml delete mode 100644 android-libraries/ActionBarSherlock/res/values/abs__config.xml delete mode 100644 android-libraries/ActionBarSherlock/res/values/abs__dimens.xml delete mode 100644 android-libraries/ActionBarSherlock/res/values/abs__ids.xml delete mode 100644 android-libraries/ActionBarSherlock/res/values/abs__strings.xml delete mode 100644 android-libraries/ActionBarSherlock/res/values/abs__styles.xml delete mode 100644 android-libraries/ActionBarSherlock/res/values/abs__themes.xml delete mode 100644 android-libraries/ActionBarSherlock/res/values/strings.xml delete mode 100644 android-libraries/ActionBarSherlock/src/android/support/v4/app/_ActionBarSherlockTrojanHorse.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/ActionBarSherlock.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/app/ActionBar.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/app/SherlockActivity.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/app/SherlockDialogFragment.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/app/SherlockExpandableListActivity.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/app/SherlockFragment.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/app/SherlockFragmentActivity.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/app/SherlockListActivity.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/app/SherlockListFragment.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/app/SherlockPreferenceActivity.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/ActionBarSherlockCompat.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/ActionBarSherlockNative.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/ResourcesCompat.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/app/ActionBarImpl.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/app/ActionBarWrapper.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/Animator.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/AnimatorListenerAdapter.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/AnimatorSet.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/FloatEvaluator.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/FloatKeyframeSet.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/IntEvaluator.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/IntKeyframeSet.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/Keyframe.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/KeyframeSet.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/ObjectAnimator.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/PropertyValuesHolder.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/TypeEvaluator.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/ValueAnimator.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/view/NineViewGroup.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/view/animation/AnimatorProxy.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/widget/NineFrameLayout.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/widget/NineHorizontalScrollView.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/widget/NineLinearLayout.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/ActionProviderWrapper.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/StandaloneActionMode.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/View_HasStateListenerSupport.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/View_OnAttachStateChangeListener.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/ActionMenu.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/ActionMenuItem.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/ActionMenuItemView.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/ActionMenuPresenter.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/ActionMenuView.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/BaseMenuPresenter.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/ListMenuItemView.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/MenuBuilder.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/MenuItemImpl.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/MenuItemWrapper.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/MenuPopupHelper.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/MenuPresenter.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/MenuView.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/MenuWrapper.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/SubMenuBuilder.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/SubMenuWrapper.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/AbsActionBarView.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/ActionBarContainer.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/ActionBarContextView.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/ActionBarView.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/CapitalizingButton.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/CapitalizingTextView.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/FakeDialogPhoneWindow.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/IcsAbsSpinner.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/IcsAdapterView.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/IcsLinearLayout.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/IcsListPopupWindow.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/IcsProgressBar.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/IcsSpinner.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/IcsView.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/ScrollingTabContainerView.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/view/ActionMode.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/view/ActionProvider.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/view/CollapsibleActionView.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/view/Menu.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/view/MenuInflater.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/view/MenuItem.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/view/SubMenu.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/view/Window.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/widget/ActivityChooserModel.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/widget/ActivityChooserView.java delete mode 100644 android-libraries/ActionBarSherlock/src/com/actionbarsherlock/widget/ShareActionProvider.java delete mode 100644 android-libraries/TreeViewList/.classpath delete mode 100644 android-libraries/TreeViewList/.project delete mode 100644 android-libraries/TreeViewList/AndroidManifest.xml delete mode 100644 android-libraries/TreeViewList/gen/pl/polidea/treeview/BuildConfig.java delete mode 100644 android-libraries/TreeViewList/gen/pl/polidea/treeview/R.java delete mode 100644 android-libraries/TreeViewList/proguard.cfg delete mode 100644 android-libraries/TreeViewList/project.properties delete mode 100644 android-libraries/TreeViewList/res/drawable-hdpi/collapsed.png delete mode 100644 android-libraries/TreeViewList/res/drawable-hdpi/expanded.png delete mode 100644 android-libraries/TreeViewList/res/drawable-hdpi/ic_launcher.png delete mode 100644 android-libraries/TreeViewList/res/drawable-ldpi/collapsed.png delete mode 100644 android-libraries/TreeViewList/res/drawable-ldpi/expanded.png delete mode 100644 android-libraries/TreeViewList/res/drawable-ldpi/ic_launcher.png delete mode 100644 android-libraries/TreeViewList/res/drawable-mdpi/collapsed.png delete mode 100644 android-libraries/TreeViewList/res/drawable-mdpi/expanded.png delete mode 100644 android-libraries/TreeViewList/res/drawable-mdpi/ic_launcher.png delete mode 100644 android-libraries/TreeViewList/res/drawable/divider.xml delete mode 100644 android-libraries/TreeViewList/res/drawable/list_selector_background.xml delete mode 100644 android-libraries/TreeViewList/res/drawable/list_selector_background_disabled.9.png delete mode 100644 android-libraries/TreeViewList/res/drawable/list_selector_background_focus.9.png delete mode 100644 android-libraries/TreeViewList/res/drawable/list_selector_background_longpress.9.png delete mode 100644 android-libraries/TreeViewList/res/drawable/list_selector_background_pressed.9.png delete mode 100644 android-libraries/TreeViewList/res/drawable/list_selector_background_transition.xml delete mode 100644 android-libraries/TreeViewList/res/layout/tree_list_item_wrapper.xml delete mode 100644 android-libraries/TreeViewList/res/values/attrs.xml delete mode 100644 android-libraries/TreeViewList/res/values/styles.xml delete mode 100644 android-libraries/TreeViewList/src/pl/polidea/treeview/AbstractTreeViewAdapter.java delete mode 100644 android-libraries/TreeViewList/src/pl/polidea/treeview/InMemoryTreeNode.java delete mode 100644 android-libraries/TreeViewList/src/pl/polidea/treeview/InMemoryTreeStateManager.java delete mode 100644 android-libraries/TreeViewList/src/pl/polidea/treeview/NodeAlreadyInTreeException.java delete mode 100644 android-libraries/TreeViewList/src/pl/polidea/treeview/NodeNotInTreeException.java delete mode 100644 android-libraries/TreeViewList/src/pl/polidea/treeview/TreeBuilder.java delete mode 100644 android-libraries/TreeViewList/src/pl/polidea/treeview/TreeConfigurationException.java delete mode 100644 android-libraries/TreeViewList/src/pl/polidea/treeview/TreeNodeInfo.java delete mode 100644 android-libraries/TreeViewList/src/pl/polidea/treeview/TreeStateManager.java delete mode 100644 android-libraries/TreeViewList/src/pl/polidea/treeview/TreeViewList.java delete mode 100644 android-libraries/TreeViewList/src/pl/polidea/treeview/overview.html delete mode 100644 android-libraries/TreeViewList/src/pl/polidea/treeview/package-info.java delete mode 100644 android-libraries/achartengine/.classpath delete mode 100644 android-libraries/achartengine/.project delete mode 100644 android-libraries/achartengine/AndroidManifest.xml delete mode 100644 android-libraries/achartengine/extra/LICENSE-2.0.txt delete mode 100644 android-libraries/achartengine/project.properties delete mode 100644 android-libraries/achartengine/src/org/achartengine/ChartFactory.java delete mode 100644 android-libraries/achartengine/src/org/achartengine/GraphicalActivity.java delete mode 100644 android-libraries/achartengine/src/org/achartengine/GraphicalView.java delete mode 100644 android-libraries/achartengine/src/org/achartengine/ITouchHandler.java delete mode 100644 android-libraries/achartengine/src/org/achartengine/TouchHandler.java delete mode 100644 android-libraries/achartengine/src/org/achartengine/TouchHandlerOld.java delete mode 100644 android-libraries/achartengine/src/org/achartengine/chart/AbstractChart.java delete mode 100644 android-libraries/achartengine/src/org/achartengine/chart/BarChart.java delete mode 100644 android-libraries/achartengine/src/org/achartengine/chart/BubbleChart.java delete mode 100644 android-libraries/achartengine/src/org/achartengine/chart/ClickableArea.java delete mode 100644 android-libraries/achartengine/src/org/achartengine/chart/CombinedXYChart.java delete mode 100644 android-libraries/achartengine/src/org/achartengine/chart/CubicLineChart.java delete mode 100644 android-libraries/achartengine/src/org/achartengine/chart/DialChart.java delete mode 100644 android-libraries/achartengine/src/org/achartengine/chart/DoughnutChart.java delete mode 100644 android-libraries/achartengine/src/org/achartengine/chart/LineChart.java delete mode 100644 android-libraries/achartengine/src/org/achartengine/chart/PieChart.java delete mode 100644 android-libraries/achartengine/src/org/achartengine/chart/PieMapper.java delete mode 100644 android-libraries/achartengine/src/org/achartengine/chart/PieSegment.java delete mode 100644 android-libraries/achartengine/src/org/achartengine/chart/PointStyle.java delete mode 100644 android-libraries/achartengine/src/org/achartengine/chart/RangeBarChart.java delete mode 100644 android-libraries/achartengine/src/org/achartengine/chart/RangeStackedBarChart.java delete mode 100644 android-libraries/achartengine/src/org/achartengine/chart/RoundChart.java delete mode 100644 android-libraries/achartengine/src/org/achartengine/chart/ScatterChart.java delete mode 100644 android-libraries/achartengine/src/org/achartengine/chart/TimeChart.java delete mode 100644 android-libraries/achartengine/src/org/achartengine/chart/XYChart.java delete mode 100644 android-libraries/achartengine/src/org/achartengine/chart/package.html delete mode 100644 android-libraries/achartengine/src/org/achartengine/image/zoom-1.png delete mode 100644 android-libraries/achartengine/src/org/achartengine/image/zoom_in.png delete mode 100644 android-libraries/achartengine/src/org/achartengine/image/zoom_out.png delete mode 100644 android-libraries/achartengine/src/org/achartengine/model/CategorySeries.java delete mode 100644 android-libraries/achartengine/src/org/achartengine/model/MultipleCategorySeries.java delete mode 100644 android-libraries/achartengine/src/org/achartengine/model/Point.java delete mode 100644 android-libraries/achartengine/src/org/achartengine/model/RangeCategorySeries.java delete mode 100644 android-libraries/achartengine/src/org/achartengine/model/SeriesSelection.java delete mode 100644 android-libraries/achartengine/src/org/achartengine/model/TimeSeries.java delete mode 100644 android-libraries/achartengine/src/org/achartengine/model/XYMultipleSeriesDataset.java delete mode 100644 android-libraries/achartengine/src/org/achartengine/model/XYSeries.java delete mode 100644 android-libraries/achartengine/src/org/achartengine/model/XYValueSeries.java delete mode 100644 android-libraries/achartengine/src/org/achartengine/model/package.html delete mode 100644 android-libraries/achartengine/src/org/achartengine/package.html delete mode 100644 android-libraries/achartengine/src/org/achartengine/renderer/BasicStroke.java delete mode 100644 android-libraries/achartengine/src/org/achartengine/renderer/DefaultRenderer.java delete mode 100644 android-libraries/achartengine/src/org/achartengine/renderer/DialRenderer.java delete mode 100644 android-libraries/achartengine/src/org/achartengine/renderer/SimpleSeriesRenderer.java delete mode 100644 android-libraries/achartengine/src/org/achartengine/renderer/XYMultipleSeriesRenderer.java delete mode 100644 android-libraries/achartengine/src/org/achartengine/renderer/XYSeriesRenderer.java delete mode 100644 android-libraries/achartengine/src/org/achartengine/renderer/package.html delete mode 100644 android-libraries/achartengine/src/org/achartengine/tools/AbstractTool.java delete mode 100644 android-libraries/achartengine/src/org/achartengine/tools/FitZoom.java delete mode 100644 android-libraries/achartengine/src/org/achartengine/tools/Pan.java delete mode 100644 android-libraries/achartengine/src/org/achartengine/tools/PanListener.java delete mode 100644 android-libraries/achartengine/src/org/achartengine/tools/Zoom.java delete mode 100644 android-libraries/achartengine/src/org/achartengine/tools/ZoomEvent.java delete mode 100644 android-libraries/achartengine/src/org/achartengine/tools/ZoomListener.java delete mode 100644 android-libraries/achartengine/src/org/achartengine/util/IndexXYMap.java delete mode 100644 android-libraries/achartengine/src/org/achartengine/util/MathHelper.java delete mode 100644 android-libraries/achartengine/src/org/achartengine/util/XYEntry.java delete mode 100644 android-libraries/achartengine/src/org/achartengine/util/package.html delete mode 100644 android/.classpath delete mode 100644 android/.project delete mode 100644 android/AndroidManifest.xml delete mode 100644 android/libs/android-support-v4.jar delete mode 100644 android/lint.xml delete mode 100644 android/proguard.cfg delete mode 100644 android/project.properties delete mode 100644 android/res/drawable-hdpi/arrow_down_float.png delete mode 100644 android/res/drawable-hdpi/arrow_up_float.png delete mode 100644 android/res/drawable-hdpi/ic_menu_add.png delete mode 100644 android/res/drawable-hdpi/ic_menu_archive.png delete mode 100644 android/res/drawable-hdpi/ic_menu_download.png delete mode 100644 android/res/drawable-hdpi/ic_menu_info_details.png delete mode 100644 android/res/drawable-hdpi/ic_menu_preferences.png delete mode 100644 android/res/drawable-hdpi/ic_menu_save.png delete mode 100644 android/res/drawable-hdpi/or_launcher.png delete mode 100644 android/res/drawable-ldpi/arrow_down_float.png delete mode 100644 android/res/drawable-ldpi/arrow_up_float.png delete mode 100644 android/res/drawable-ldpi/ic_menu_add.png delete mode 100644 android/res/drawable-ldpi/ic_menu_archive.png delete mode 100644 android/res/drawable-ldpi/ic_menu_info_details.png delete mode 100644 android/res/drawable-ldpi/ic_menu_preferences.png delete mode 100644 android/res/drawable-ldpi/ic_menu_save.png delete mode 100644 android/res/drawable-ldpi/or_launcher.png delete mode 100644 android/res/drawable-mdpi/arrow_down_float.png delete mode 100644 android/res/drawable-mdpi/arrow_up_float.png delete mode 100644 android/res/drawable-mdpi/ic_directory.png delete mode 100644 android/res/drawable-mdpi/ic_menu_add.png delete mode 100644 android/res/drawable-mdpi/ic_menu_archive.png delete mode 100644 android/res/drawable-mdpi/ic_menu_info_details.png delete mode 100644 android/res/drawable-mdpi/ic_menu_preferences.png delete mode 100644 android/res/drawable-mdpi/ic_menu_save.png delete mode 100644 android/res/drawable-mdpi/ic_motorbrowser.png delete mode 100644 android/res/drawable-mdpi/ic_star_select.png delete mode 100644 android/res/drawable-mdpi/ic_star_unselected.png delete mode 100644 android/res/drawable-mdpi/or_launcher.png delete mode 100644 android/res/drawable-xhdpi/ic_menu_add.png delete mode 100644 android/res/drawable-xhdpi/ic_menu_archive.png delete mode 100644 android/res/drawable-xhdpi/ic_menu_download.png delete mode 100644 android/res/drawable-xhdpi/ic_menu_info_details.png delete mode 100644 android/res/drawable-xhdpi/ic_menu_preferences.png delete mode 100644 android/res/drawable-xhdpi/ic_menu_save.png delete mode 100644 android/res/drawable-xhdpi/or_launcher.png delete mode 100644 android/res/drawable/filebrowser_home.xml delete mode 100644 android/res/drawable/openrocket.png delete mode 100644 android/res/drawable/rocketglobe.png delete mode 100644 android/res/drawable/sf_donate.png delete mode 100644 android/res/drawable/simulation_state.xml delete mode 100644 android/res/drawable/simulation_state_green.xml delete mode 100644 android/res/drawable/simulation_state_red.xml delete mode 100644 android/res/drawable/simulation_state_yellow.xml delete mode 100644 android/res/drawable/starfield.png delete mode 100644 android/res/layout-land/main.xml delete mode 100644 android/res/layout-land/simulation_event_item.xml delete mode 100644 android/res/layout-large-land/motorbrowser.xml delete mode 100644 android/res/layout-large-land/openrocketviewer.xml delete mode 100644 android/res/layout-xlarge-port/motorbrowser.xml delete mode 100644 android/res/layout-xlarge-port/openrocketviewer.xml delete mode 100644 android/res/layout/component_list_item.xml delete mode 100644 android/res/layout/filebrowser_list_item.xml delete mode 100644 android/res/layout/main.xml delete mode 100644 android/res/layout/motor_config_delay_dialog.xml delete mode 100644 android/res/layout/motor_config_item.xml delete mode 100644 android/res/layout/motor_detail_form.xml delete mode 100644 android/res/layout/motor_list_child.xml delete mode 100644 android/res/layout/motor_list_dialog.xml delete mode 100644 android/res/layout/motor_list_group.xml delete mode 100644 android/res/layout/motorbrowser.xml delete mode 100644 android/res/layout/openrocketviewer.xml delete mode 100644 android/res/layout/rocket_component.xml delete mode 100644 android/res/layout/rocket_configurations.xml delete mode 100644 android/res/layout/rocket_overview.xml delete mode 100644 android/res/layout/rocket_simulations.xml delete mode 100644 android/res/layout/simplefilebrowser.xml delete mode 100644 android/res/layout/simulation_condition_dialog.xml delete mode 100644 android/res/layout/simulation_event_dialog.xml delete mode 100644 android/res/layout/simulation_event_item.xml delete mode 100644 android/res/layout/simulation_graph_activity.xml delete mode 100644 android/res/layout/simulation_list_item.xml delete mode 100644 android/res/layout/simulation_plot_config_dialog.xml delete mode 100644 android/res/layout/simulation_plot_config_event_list_item.xml delete mode 100644 android/res/layout/tcqueryform.xml delete mode 100644 android/res/menu/main_menu.xml delete mode 100644 android/res/menu/motor_browser_option_menu.xml delete mode 100644 android/res/menu/rocket_viewer_configurations_option_menu.xml delete mode 100644 android/res/menu/rocket_viewer_option_menu.xml delete mode 100644 android/res/menu/rocket_viewer_simulation_option_menu.xml delete mode 100644 android/res/menu/simulation_option_menu.xml delete mode 100644 android/res/values-fr/strings.xml delete mode 100644 android/res/values-v11/styles.xml delete mode 100644 android/res/values/pref_strings.xml delete mode 100644 android/res/values/simulation_states.xml delete mode 100644 android/res/values/strings.xml delete mode 100644 android/res/values/styles.xml delete mode 100644 android/res/xml/preferences.xml delete mode 100644 android/src/build.properties delete mode 100644 android/src/net/sf/openrocket/android/AboutDialogFragment.java delete mode 100644 android/src/net/sf/openrocket/android/ActivityHelpers.java delete mode 100644 android/src/net/sf/openrocket/android/Application.java delete mode 100644 android/src/net/sf/openrocket/android/CurrentRocket.java delete mode 100644 android/src/net/sf/openrocket/android/CurrentRocketHolder.java delete mode 100644 android/src/net/sf/openrocket/android/Main.java delete mode 100644 android/src/net/sf/openrocket/android/MotorDatabaseAdapter.java delete mode 100644 android/src/net/sf/openrocket/android/PreferencesActivity.java delete mode 100644 android/src/net/sf/openrocket/android/PreferencesAdapter.java delete mode 100644 android/src/net/sf/openrocket/android/db/ConversionUtils.java delete mode 100644 android/src/net/sf/openrocket/android/db/DbAdapter.java delete mode 100644 android/src/net/sf/openrocket/android/db/MotorDao.java delete mode 100644 android/src/net/sf/openrocket/android/events/ChangeEventBroadcastReceiver.java delete mode 100644 android/src/net/sf/openrocket/android/events/Events.java delete mode 100644 android/src/net/sf/openrocket/android/filebrowser/AlphanumComparator.java delete mode 100644 android/src/net/sf/openrocket/android/filebrowser/SimpleFileBrowser.java delete mode 100644 android/src/net/sf/openrocket/android/motor/BurnPlotActivity.java delete mode 100644 android/src/net/sf/openrocket/android/motor/BurnPlotFragment.java delete mode 100644 android/src/net/sf/openrocket/android/motor/ExtendedThrustCurveMotor.java delete mode 100644 android/src/net/sf/openrocket/android/motor/MotorBrowserActivity.java delete mode 100644 android/src/net/sf/openrocket/android/motor/MotorDelayDialogFragment.java delete mode 100644 android/src/net/sf/openrocket/android/motor/MotorDetailsFragment.java delete mode 100644 android/src/net/sf/openrocket/android/motor/MotorListDialogFragment.java delete mode 100644 android/src/net/sf/openrocket/android/motor/MotorListFragment.java delete mode 100644 android/src/net/sf/openrocket/android/rocket/Component.java delete mode 100644 android/src/net/sf/openrocket/android/rocket/Configurations.java delete mode 100644 android/src/net/sf/openrocket/android/rocket/ErrorLoadingFileDialogFragment.java delete mode 100644 android/src/net/sf/openrocket/android/rocket/MissingMotorDialogFragment.java delete mode 100644 android/src/net/sf/openrocket/android/rocket/MissingMotorHelpers.java delete mode 100644 android/src/net/sf/openrocket/android/rocket/MotorConfigSpinner.java delete mode 100644 android/src/net/sf/openrocket/android/rocket/OpenRocketLoaderActivity.java delete mode 100644 android/src/net/sf/openrocket/android/rocket/OpenRocketLoaderFragment.java delete mode 100644 android/src/net/sf/openrocket/android/rocket/OpenRocketLoaderResult.java delete mode 100644 android/src/net/sf/openrocket/android/rocket/OpenRocketSaverFragment.java delete mode 100644 android/src/net/sf/openrocket/android/rocket/OpenRocketViewer.java delete mode 100644 android/src/net/sf/openrocket/android/rocket/Overview.java delete mode 100644 android/src/net/sf/openrocket/android/rocket/RocketComponentTreeAdapter.java delete mode 100644 android/src/net/sf/openrocket/android/rocket/WarningDialogFragment.java delete mode 100644 android/src/net/sf/openrocket/android/simservice/SimulationService.java delete mode 100644 android/src/net/sf/openrocket/android/simservice/SimulationTask.java delete mode 100644 android/src/net/sf/openrocket/android/simulation/SimulationChart.java delete mode 100644 android/src/net/sf/openrocket/android/simulation/SimulationEditFragment.java delete mode 100644 android/src/net/sf/openrocket/android/simulation/SimulationEventsDialog.java delete mode 100644 android/src/net/sf/openrocket/android/simulation/SimulationListItem.java delete mode 100644 android/src/net/sf/openrocket/android/simulation/SimulationPlotConfigDialog.java delete mode 100644 android/src/net/sf/openrocket/android/simulation/SimulationViewActivity.java delete mode 100644 android/src/net/sf/openrocket/android/simulation/SimulationViewFragment.java delete mode 100644 android/src/net/sf/openrocket/android/simulation/Simulations.java delete mode 100644 android/src/net/sf/openrocket/android/thrustcurve/Base64Decoder.java delete mode 100644 android/src/net/sf/openrocket/android/thrustcurve/DownloadRequest.java delete mode 100644 android/src/net/sf/openrocket/android/thrustcurve/DownloadResponse.java delete mode 100644 android/src/net/sf/openrocket/android/thrustcurve/DownloadResponseParser.java delete mode 100644 android/src/net/sf/openrocket/android/thrustcurve/MotorBurnFile.java delete mode 100644 android/src/net/sf/openrocket/android/thrustcurve/SearchRequest.java delete mode 100644 android/src/net/sf/openrocket/android/thrustcurve/SearchResponse.java delete mode 100644 android/src/net/sf/openrocket/android/thrustcurve/SearchResponseParser.java delete mode 100644 android/src/net/sf/openrocket/android/thrustcurve/SupportedFileTypes.java delete mode 100644 android/src/net/sf/openrocket/android/thrustcurve/TCMissingMotorDownloadAction.java delete mode 100644 android/src/net/sf/openrocket/android/thrustcurve/TCMotor.java delete mode 100644 android/src/net/sf/openrocket/android/thrustcurve/TCQueryAction.java delete mode 100644 android/src/net/sf/openrocket/android/thrustcurve/TCQueryActivity.java delete mode 100644 android/src/net/sf/openrocket/android/thrustcurve/TCSearchAction.java delete mode 100644 android/src/net/sf/openrocket/android/thrustcurve/ThrustCurveAPI.java delete mode 100644 android/src/net/sf/openrocket/android/util/AndroidLogWrapper.java delete mode 100644 android/src/net/sf/openrocket/android/util/ErrorDialogFragment.java delete mode 100644 android/src/net/sf/openrocket/android/util/ExpandableListFragment.java delete mode 100644 android/src/net/sf/openrocket/android/util/PersistentExpandableListFragment.java delete mode 100644 android/src/net/sf/openrocket/android/util/PersistentExpandableListView.java delete mode 100644 android/src/net/sf/openrocket/android/util/ProgressDialogFragment.java diff --git a/android-libraries/ActionBarSherlock/.classpath b/android-libraries/ActionBarSherlock/.classpath deleted file mode 100644 index 8531be106..000000000 --- a/android-libraries/ActionBarSherlock/.classpath +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/android-libraries/ActionBarSherlock/.project b/android-libraries/ActionBarSherlock/.project deleted file mode 100644 index cbcf5a224..000000000 --- a/android-libraries/ActionBarSherlock/.project +++ /dev/null @@ -1,33 +0,0 @@ - - - ActionBarSherlock - - - - - - com.android.ide.eclipse.adt.ResourceManagerBuilder - - - - - com.android.ide.eclipse.adt.PreCompilerBuilder - - - - - org.eclipse.jdt.core.javabuilder - - - - - com.android.ide.eclipse.adt.ApkBuilder - - - - - - com.android.ide.eclipse.adt.AndroidNature - org.eclipse.jdt.core.javanature - - diff --git a/android-libraries/ActionBarSherlock/AndroidManifest.xml b/android-libraries/ActionBarSherlock/AndroidManifest.xml deleted file mode 100644 index c4a75f32c..000000000 --- a/android-libraries/ActionBarSherlock/AndroidManifest.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/android-libraries/ActionBarSherlock/gen/com/actionbarsherlock/BuildConfig.java b/android-libraries/ActionBarSherlock/gen/com/actionbarsherlock/BuildConfig.java deleted file mode 100644 index ceb2ab073..000000000 --- a/android-libraries/ActionBarSherlock/gen/com/actionbarsherlock/BuildConfig.java +++ /dev/null @@ -1,6 +0,0 @@ -/** Automatically generated file. DO NOT MODIFY */ -package com.actionbarsherlock; - -public final class BuildConfig { - public final static boolean DEBUG = true; -} \ No newline at end of file diff --git a/android-libraries/ActionBarSherlock/gen/com/actionbarsherlock/R.java b/android-libraries/ActionBarSherlock/gen/com/actionbarsherlock/R.java deleted file mode 100644 index b48b62429..000000000 --- a/android-libraries/ActionBarSherlock/gen/com/actionbarsherlock/R.java +++ /dev/null @@ -1,2813 +0,0 @@ -/* AUTO-GENERATED FILE. DO NOT MODIFY. - * - * This class was automatically generated by the - * aapt tool from the resource data it found. It - * should not be modified by hand. - */ - -package com.actionbarsherlock; - -public final class R { - public static final class attr { - /** Specified if we are forcing an action item overflow menu. -

Must be a boolean value, either "true" or "false". -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. - */ - public static int absForceOverflow=0x7f010039; - /** Custom divider drawable to use for elements in the action bar. -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - */ - public static int actionBarDivider=0x7f01000e; - /** Custom item state list drawable background for action bar items. -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - */ - public static int actionBarItemBackground=0x7f01000f; - /** Size of the Action Bar, including the contextual - bar used to present Action Modes. -

May be a dimension value, which is a floating point number appended with a unit such as "14.5sp". -Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size), -in (inches), mm (millimeters). -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. -

May be one of the following constant values.

- ---- - -
ConstantValueDescription
wrap_content0
- */ - public static int actionBarSize=0x7f01000d; - /** Reference to a style for the split Action Bar. This style - controls the split component that holds the menu/action - buttons. actionBarStyle is still used for the primary - bar. -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - */ - public static int actionBarSplitStyle=0x7f01000b; - /** Reference to a style for the Action Bar -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - */ - public static int actionBarStyle=0x7f01000a; - /**

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - */ - public static int actionBarTabBarStyle=0x7f010007; - /** Default style for tabs within an action bar -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - */ - public static int actionBarTabStyle=0x7f010006; - /**

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - */ - public static int actionBarTabTextStyle=0x7f010008; - /** Reference to a theme that should be used to inflate widgets - and layouts destined for the action bar. Most of the time - this will be a reference to the current theme, but when - the action bar has a significantly different contrast - profile than the rest of the activity the difference - can become important. If this is set to @null the current - theme will be used. -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - */ - public static int actionBarWidgetTheme=0x7f01000c; - /**

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - */ - public static int actionButtonStyle=0x7f01002b; - /**

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - */ - public static int actionDropDownStyle=0x7f01002a; - /** TextAppearance style that will be applied to text that - appears within action menu items. -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - */ - public static int actionMenuTextAppearance=0x7f010010; - /** Color for text that appears within action menu items. -

May be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

May be a color value, in the form of "#rgb", "#argb", -"#rrggbb", or "#aarrggbb". - */ - public static int actionMenuTextColor=0x7f010011; - /** Background drawable to use for action mode UI -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - */ - public static int actionModeBackground=0x7f010014; - /**

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - */ - public static int actionModeCloseButtonStyle=0x7f010013; - /** Drawable to use for the close action mode button -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - */ - public static int actionModeCloseDrawable=0x7f010016; - /** PopupWindow style to use for action modes when showing as a window overlay. -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - */ - public static int actionModePopupWindowStyle=0x7f010018; - /** Drawable to use for the Share action button in WebView selection action modes -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - */ - public static int actionModeShareDrawable=0x7f010017; - /** Background drawable to use for action mode UI in the lower split bar -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - */ - public static int actionModeSplitBackground=0x7f010015; - /**

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - */ - public static int actionModeStyle=0x7f010012; - /**

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - */ - public static int actionOverflowButtonStyle=0x7f010009; - /**

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - */ - public static int actionSpinnerItemStyle=0x7f010030; - /** Drawable used as a background for activated items. -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - */ - public static int activatedBackgroundIndicator=0x7f010038; - /** Default ActivityChooserView style. -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - */ - public static int activityChooserViewStyle=0x7f010037; - /**

May be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

May be a color value, in the form of "#rgb", "#argb", -"#rrggbb", or "#aarrggbb". - */ - public static int background=0x7f010002; - /**

May be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

May be a color value, in the form of "#rgb", "#argb", -"#rrggbb", or "#aarrggbb". - */ - public static int backgroundSplit=0x7f010003; - /** Specifies a background drawable for a second stacked row of the action bar. -

May be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

May be a color value, in the form of "#rgb", "#argb", -"#rrggbb", or "#aarrggbb". - */ - public static int backgroundStacked=0x7f010040; - /** Small Button style. -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - */ - public static int buttonStyleSmall=0x7f010019; - /** Specifies a layout for custom navigation. Overrides navigationMode. -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - */ - public static int customNavigationLayout=0x7f010041; - /** Options affecting how the action bar is displayed. -

Must be one or more (separated by '|') of the following constant values.

- ---- - - - - - - -
ConstantValueDescription
useLogo0x1
showHome0x2
homeAsUp0x4
showTitle0x8
showCustom0x10
disableHome0x20
- */ - public static int displayOptions=0x7f01003b; - /**

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - */ - public static int divider=0x7f010005; - /** Drawable to use for generic vertical dividers. -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - */ - public static int dividerVertical=0x7f010029; - /**

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - */ - public static int dropDownListViewStyle=0x7f01002d; - /**

Must be a dimension value, which is a floating point number appended with a unit such as "14.5sp". -Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size), -in (inches), mm (millimeters). -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. - */ - public static int dropdownListPreferredItemHeight=0x7f01002f; - /** The drawable to show in the button for expanding the activities overflow popup. - Note: Clients would like to set this drawable - as a clue about the action the chosen activity will perform. For - example, if share activity is to be chosen the drawable should - give a clue that sharing is to be performed. - -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - */ - public static int expandActivityOverflowButtonDrawable=0x7f010050; - /** Default background for the menu header. -

May be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

May be a color value, in the form of "#rgb", "#argb", -"#rrggbb", or "#aarrggbb". - */ - public static int headerBackground=0x7f01004a; - /**

Must be a dimension value, which is a floating point number appended with a unit such as "14.5sp". -Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size), -in (inches), mm (millimeters). -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. - */ - public static int height=0x7f010004; - /**

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - */ - public static int homeAsUpIndicator=0x7f01002c; - /** Specifies a layout to use for the "home" section of the action bar. -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - */ - public static int homeLayout=0x7f010042; - /** Default horizontal divider between rows of menu items. -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - */ - public static int horizontalDivider=0x7f010048; - /** Specifies the drawable used for the application icon. -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - */ - public static int icon=0x7f01003e; - /** Specifies a style resource to use for an indeterminate progress spinner. -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - */ - public static int indeterminateProgressStyle=0x7f010044; - /** The maximal number of items initially shown in the activity list. -

Must be a string value, using '\\;' to escape characters such as '\\n' or '\\uxxxx' for a unicode character. -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. - */ - public static int initialActivityCount=0x7f01004f; - /** Default background for each menu item. -

May be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

May be a color value, in the form of "#rgb", "#argb", -"#rrggbb", or "#aarrggbb". - */ - public static int itemBackground=0x7f01004b; - /** Default disabled icon alpha for each menu item that shows an icon. -

Must be a floating point value, such as "1.2". -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. - */ - public static int itemIconDisabledAlpha=0x7f01004d; - /** Specifies padding that should be applied to the left and right sides of - system-provided items in the bar. -

Must be a dimension value, which is a floating point number appended with a unit such as "14.5sp". -Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size), -in (inches), mm (millimeters). -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. - */ - public static int itemPadding=0x7f010046; - /** Default appearance of menu item text. -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - */ - public static int itemTextAppearance=0x7f010047; - /**

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - */ - public static int listPopupWindowStyle=0x7f010036; - /** A smaller, sleeker list item height. -

Must be a dimension value, which is a floating point number appended with a unit such as "14.5sp". -Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size), -in (inches), mm (millimeters). -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. - */ - public static int listPreferredItemHeightSmall=0x7f010023; - /** The preferred padding along the left edge of list items. -

Must be a dimension value, which is a floating point number appended with a unit such as "14.5sp". -Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size), -in (inches), mm (millimeters). -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. - */ - public static int listPreferredItemPaddingLeft=0x7f010024; - /** The preferred padding along the right edge of list items. -

Must be a dimension value, which is a floating point number appended with a unit such as "14.5sp". -Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size), -in (inches), mm (millimeters). -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. - */ - public static int listPreferredItemPaddingRight=0x7f010025; - /** Specifies the drawable used for the application logo. -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - */ - public static int logo=0x7f01003f; - /** The type of navigation to use. -

Must be one of the following constant values.

- ---- - - - -
ConstantValueDescription
normal0 Normal static title text
listMode1 The action bar will use a selection list for navigation.
tabMode2 The action bar will use a series of horizontal tabs for navigation.
- */ - public static int navigationMode=0x7f01003a; - /**

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - */ - public static int popupMenuStyle=0x7f01002e; - /** Whether space should be reserved in layout when an icon is missing. -

Must be a boolean value, either "true" or "false". -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. - */ - public static int preserveIconSpacing=0x7f01004e; - /** Specifies the horizontal padding on either end for an embedded progress bar. -

Must be a dimension value, which is a floating point number appended with a unit such as "14.5sp". -Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size), -in (inches), mm (millimeters). -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. - */ - public static int progressBarPadding=0x7f010045; - /** Specifies a style resource to use for an embedded progress bar. -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - */ - public static int progressBarStyle=0x7f010043; - /**

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - */ - public static int spinnerDropDownItemStyle=0x7f010022; - /**

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - */ - public static int spinnerItemStyle=0x7f010021; - /** Specifies subtitle text used for navigationMode="normal" -

Must be a string value, using '\\;' to escape characters such as '\\n' or '\\uxxxx' for a unicode character. -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. - */ - public static int subtitle=0x7f01003d; - /**

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - */ - public static int subtitleTextStyle=0x7f010001; - /** Text color, typeface, size, and style for the text inside of a popup menu. -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - */ - public static int textAppearanceLargePopupMenu=0x7f01001b; - /** The preferred TextAppearance for the primary text of small list items. -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - */ - public static int textAppearanceListItemSmall=0x7f010026; - /** Text color, typeface, size, and style for "small" text. Defaults to secondary text color. -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - */ - public static int textAppearanceSmall=0x7f01001d; - /** Text color, typeface, size, and style for small text inside of a popup menu. -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - */ - public static int textAppearanceSmallPopupMenu=0x7f01001c; - /**

Must be a color value, in the form of "#rgb", "#argb", -"#rrggbb", or "#aarrggbb". -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. - */ - public static int textColorPrimary=0x7f01001e; - /**

Must be a color value, in the form of "#rgb", "#argb", -"#rrggbb", or "#aarrggbb". -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. - */ - public static int textColorPrimaryDisableOnly=0x7f01001f; - /**

Must be a color value, in the form of "#rgb", "#argb", -"#rrggbb", or "#aarrggbb". -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. - */ - public static int textColorPrimaryInverse=0x7f010020; - /** Specifies title text used for navigationMode="normal" -

Must be a string value, using '\\;' to escape characters such as '\\n' or '\\uxxxx' for a unicode character. -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. - */ - public static int title=0x7f01003c; - /**

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - */ - public static int titleTextStyle=0x7f010000; - /** Default vertical divider between menu items. -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - */ - public static int verticalDivider=0x7f010049; - /**

Must be a boolean value, either "true" or "false". -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. - */ - public static int windowActionBar=0x7f010032; - /**

Must be a boolean value, either "true" or "false". -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. - */ - public static int windowActionBarOverlay=0x7f010033; - /**

Must be a boolean value, either "true" or "false". -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. - */ - public static int windowActionModeOverlay=0x7f010034; - /** Default animations for the menu. -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - */ - public static int windowAnimationStyle=0x7f01004c; - /** This Drawable is overlaid over the foreground of the Window's content area, usually - to place a shadow below the title. -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - */ - public static int windowContentOverlay=0x7f01001a; - /**

Must be a dimension value, which is a floating point number appended with a unit such as "14.5sp". -Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size), -in (inches), mm (millimeters). -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. - */ - public static int windowMinWidthMajor=0x7f010027; - /**

Must be a dimension value, which is a floating point number appended with a unit such as "14.5sp". -Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size), -in (inches), mm (millimeters). -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. - */ - public static int windowMinWidthMinor=0x7f010028; - /**

Must be a boolean value, either "true" or "false". -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. - */ - public static int windowNoTitle=0x7f010031; - /**

Must be a boolean value, either "true" or "false". -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. - */ - public static int windowSplitActionBar=0x7f010035; - } - public static final class bool { - public static int abs__action_bar_embed_tabs=0x7f050000; - public static int abs__action_bar_expanded_action_views_exclusive=0x7f050002; - /** Whether action menu items should be displayed in ALLCAPS or not. - Defaults to true. If this is not appropriate for specific locales - it should be disabled in that locale's resources. - */ - public static int abs__config_actionMenuItemAllCaps=0x7f050004; - /** Whether action menu items should obey the "withText" showAsAction - flag. This may be set to false for situations where space is - extremely limited. - Whether action menu items should obey the "withText" showAsAction - flag. This may be set to false for situations where space is - extremely limited. - */ - public static int abs__config_allowActionMenuItemTextWithIcon=0x7f050005; - /** Sets whether menu shortcuts should be displayed on panel menus when - a keyboard is present. - */ - public static int abs__config_showMenuShortcutsWhenKeyboardPresent=0x7f050003; - public static int abs__split_action_bar_is_narrow=0x7f050001; - } - public static final class color { - public static int abs__background_holo_dark=0x7f060000; - public static int abs__background_holo_light=0x7f060001; - public static int abs__bright_foreground_disabled_holo_dark=0x7f060004; - public static int abs__bright_foreground_disabled_holo_light=0x7f060005; - public static int abs__bright_foreground_holo_dark=0x7f060002; - public static int abs__bright_foreground_holo_light=0x7f060003; - public static int abs__bright_foreground_inverse_holo_dark=0x7f060006; - public static int abs__bright_foreground_inverse_holo_light=0x7f060007; - public static int abs__holo_blue_light=0x7f060008; - public static int abs__primary_text_disable_only_holo_dark=0x7f060009; - public static int abs__primary_text_disable_only_holo_light=0x7f06000a; - public static int abs__primary_text_holo_dark=0x7f06000b; - public static int abs__primary_text_holo_light=0x7f06000c; - } - public static final class dimen { - /** Default height of an action bar. - Default height of an action bar. - Default height of an action bar. - Default height of an action bar. - Default height of an action bar. - Default height of an action bar. - Default height of an action bar. - Default height of an action bar. - */ - public static int abs__action_bar_default_height=0x7f070001; - /** Vertical padding around action bar icons. - Vertical padding around action bar icons. - Vertical padding around action bar icons. - Vertical padding around action bar icons. - Vertical padding around action bar icons. - Vertical padding around action bar icons. - Vertical padding around action bar icons. - Vertical padding around action bar icons. - */ - public static int abs__action_bar_icon_vertical_padding=0x7f070002; - /** Bottom margin for action bar subtitles - Bottom margin for action bar subtitles - Bottom margin for action bar subtitles - Bottom margin for action bar subtitles - Bottom margin for action bar subtitles - Bottom margin for action bar subtitles - Bottom margin for action bar subtitles - Bottom margin for action bar subtitles - */ - public static int abs__action_bar_subtitle_bottom_margin=0x7f070006; - /** Text size for action bar subtitles - Text size for action bar subtitles - Text size for action bar subtitles - Text size for action bar subtitles - Text size for action bar subtitles - Text size for action bar subtitles - Text size for action bar subtitles - Text size for action bar subtitles - */ - public static int abs__action_bar_subtitle_text_size=0x7f070004; - /** Top margin for action bar subtitles - Top margin for action bar subtitles - Top margin for action bar subtitles - Top margin for action bar subtitles - Top margin for action bar subtitles - Top margin for action bar subtitles - Top margin for action bar subtitles - Top margin for action bar subtitles - */ - public static int abs__action_bar_subtitle_top_margin=0x7f070005; - /** Text size for action bar titles - Text size for action bar titles - Text size for action bar titles - Text size for action bar titles - Text size for action bar titles - Text size for action bar titles - Text size for action bar titles - Text size for action bar titles - */ - public static int abs__action_bar_title_text_size=0x7f070003; - /** Minimum width for an action button in the menu area of an action bar - Minimum width for an action button in the menu area of an action bar - */ - public static int abs__action_button_min_width=0x7f070007; - /** Dialog title height - */ - public static int abs__alert_dialog_title_height=0x7f070008; - /** The maximum width we would prefer dialogs to be. 0 if there is no - maximum (let them grow as large as the screen). Actual values are - specified for -large and -xlarge configurations. - */ - public static int abs__config_prefDialogWidth=0x7f070000; - /** The platform's desired minimum size for a dialog's width when it - is along the major axis (that is the screen is landscape). This may - be either a fraction or a dimension. - The platform's desired minimum size for a dialog's width when it - is along the major axis (that is the screen is landscape). This may - be either a fraction or a dimension. - The platform's desired minimum size for a dialog's width when it - is along the major axis (that is the screen is landscape). This may - be either a fraction or a dimension. - */ - public static int abs__dialog_min_width_major=0x7f070009; - /** The platform's desired minimum size for a dialog's width when it - is along the minor axis (that is the screen is portrait). This may - be either a fraction or a dimension. - The platform's desired minimum size for a dialog's width when it - is along the minor axis (that is the screen is portrait). This may - be either a fraction or a dimension. - The platform's desired minimum size for a dialog's width when it - is along the minor axis (that is the screen is portrait). This may - be either a fraction or a dimension. - */ - public static int abs__dialog_min_width_minor=0x7f07000a; - /** Minimum width for an action button in the menu area of an action bar - Minimum width for an action button in the menu area of an action bar - */ - public static int action_button_min_width=0x7f07000b; - } - public static final class drawable { - public static int abs__ab_bottom_solid_dark_holo=0x7f020000; - public static int abs__ab_bottom_solid_inverse_holo=0x7f020001; - public static int abs__ab_bottom_solid_light_holo=0x7f020002; - public static int abs__ab_bottom_transparent_dark_holo=0x7f020003; - public static int abs__ab_bottom_transparent_light_holo=0x7f020004; - public static int abs__ab_share_pack_holo_dark=0x7f020005; - public static int abs__ab_share_pack_holo_light=0x7f020006; - public static int abs__ab_solid_dark_holo=0x7f020007; - public static int abs__ab_solid_light_holo=0x7f020008; - public static int abs__ab_solid_shadow_holo=0x7f020009; - public static int abs__ab_stacked_solid_dark_holo=0x7f02000a; - public static int abs__ab_stacked_solid_light_holo=0x7f02000b; - public static int abs__ab_stacked_transparent_dark_holo=0x7f02000c; - public static int abs__ab_stacked_transparent_light_holo=0x7f02000d; - public static int abs__ab_transparent_dark_holo=0x7f02000e; - public static int abs__ab_transparent_light_holo=0x7f02000f; - public static int abs__activated_background_holo_dark=0x7f020010; - public static int abs__activated_background_holo_light=0x7f020011; - public static int abs__btn_cab_done_default_holo_dark=0x7f020012; - public static int abs__btn_cab_done_default_holo_light=0x7f020013; - public static int abs__btn_cab_done_focused_holo_dark=0x7f020014; - public static int abs__btn_cab_done_focused_holo_light=0x7f020015; - public static int abs__btn_cab_done_holo_dark=0x7f020016; - public static int abs__btn_cab_done_holo_light=0x7f020017; - public static int abs__btn_cab_done_pressed_holo_dark=0x7f020018; - public static int abs__btn_cab_done_pressed_holo_light=0x7f020019; - public static int abs__cab_background_bottom_holo_dark=0x7f02001a; - public static int abs__cab_background_bottom_holo_light=0x7f02001b; - public static int abs__cab_background_top_holo_dark=0x7f02001c; - public static int abs__cab_background_top_holo_light=0x7f02001d; - public static int abs__dialog_full_holo_dark=0x7f02001e; - public static int abs__dialog_full_holo_light=0x7f02001f; - public static int abs__ic_ab_back_holo_dark=0x7f020020; - public static int abs__ic_ab_back_holo_light=0x7f020021; - public static int abs__ic_cab_done_holo_dark=0x7f020022; - public static int abs__ic_cab_done_holo_light=0x7f020023; - public static int abs__ic_menu_moreoverflow_holo_dark=0x7f020024; - public static int abs__ic_menu_moreoverflow_holo_light=0x7f020025; - public static int abs__ic_menu_moreoverflow_normal_holo_dark=0x7f020026; - public static int abs__ic_menu_moreoverflow_normal_holo_light=0x7f020027; - public static int abs__ic_menu_share_holo_dark=0x7f020028; - public static int abs__ic_menu_share_holo_light=0x7f020029; - public static int abs__item_background_holo_dark=0x7f02002a; - public static int abs__item_background_holo_light=0x7f02002b; - public static int abs__list_activated_holo=0x7f02002c; - public static int abs__list_divider_holo_dark=0x7f02002d; - public static int abs__list_divider_holo_light=0x7f02002e; - public static int abs__list_focused_holo=0x7f02002f; - public static int abs__list_longpressed_holo=0x7f020030; - public static int abs__list_pressed_holo_dark=0x7f020031; - public static int abs__list_pressed_holo_light=0x7f020032; - public static int abs__list_selector_background_transition_holo_dark=0x7f020033; - public static int abs__list_selector_background_transition_holo_light=0x7f020034; - public static int abs__list_selector_disabled_holo_dark=0x7f020035; - public static int abs__list_selector_disabled_holo_light=0x7f020036; - public static int abs__list_selector_holo_dark=0x7f020037; - public static int abs__list_selector_holo_light=0x7f020038; - public static int abs__menu_dropdown_panel_holo_dark=0x7f020039; - public static int abs__menu_dropdown_panel_holo_light=0x7f02003a; - public static int abs__progress_bg_holo_dark=0x7f02003b; - public static int abs__progress_bg_holo_light=0x7f02003c; - public static int abs__progress_horizontal_holo_dark=0x7f02003d; - public static int abs__progress_horizontal_holo_light=0x7f02003e; - public static int abs__progress_medium_holo=0x7f02003f; - public static int abs__progress_primary_holo_dark=0x7f020040; - public static int abs__progress_primary_holo_light=0x7f020041; - public static int abs__progress_secondary_holo_dark=0x7f020042; - public static int abs__progress_secondary_holo_light=0x7f020043; - public static int abs__spinner_48_inner_holo=0x7f020044; - public static int abs__spinner_48_outer_holo=0x7f020045; - public static int abs__spinner_ab_default_holo_dark=0x7f020046; - public static int abs__spinner_ab_default_holo_light=0x7f020047; - public static int abs__spinner_ab_disabled_holo_dark=0x7f020048; - public static int abs__spinner_ab_disabled_holo_light=0x7f020049; - public static int abs__spinner_ab_focused_holo_dark=0x7f02004a; - public static int abs__spinner_ab_focused_holo_light=0x7f02004b; - public static int abs__spinner_ab_holo_dark=0x7f02004c; - public static int abs__spinner_ab_holo_light=0x7f02004d; - public static int abs__spinner_ab_pressed_holo_dark=0x7f02004e; - public static int abs__spinner_ab_pressed_holo_light=0x7f02004f; - public static int abs__tab_indicator_ab_holo=0x7f020050; - public static int abs__tab_selected_focused_holo=0x7f020051; - public static int abs__tab_selected_holo=0x7f020052; - public static int abs__tab_selected_pressed_holo=0x7f020053; - public static int abs__tab_unselected_pressed_holo=0x7f020054; - public static int ic_launcher=0x7f020055; - } - public static final class id { - public static int abs__action_bar=0x7f040022; - public static int abs__action_bar_container=0x7f040021; - public static int abs__action_bar_subtitle=0x7f040011; - public static int abs__action_bar_title=0x7f040010; - public static int abs__action_context_bar=0x7f040023; - public static int abs__action_menu_divider=0x7f04000c; - public static int abs__action_menu_presenter=0x7f04000d; - public static int abs__action_mode_bar=0x7f040026; - public static int abs__action_mode_bar_stub=0x7f040025; - public static int abs__action_mode_close_button=0x7f040014; - public static int abs__activity_chooser_view_content=0x7f040015; - public static int abs__checkbox=0x7f04001e; - public static int abs__content=0x7f04001d; - public static int abs__default_activity_button=0x7f040018; - public static int abs__expand_activities_button=0x7f040016; - public static int abs__home=0x7f04000a; - public static int abs__icon=0x7f04001a; - public static int abs__image=0x7f040017; - public static int abs__imageButton=0x7f040012; - public static int abs__list_item=0x7f040019; - public static int abs__progress_circular=0x7f04000e; - public static int abs__progress_horizontal=0x7f04000f; - public static int abs__radio=0x7f040020; - public static int abs__shortcut=0x7f04001f; - public static int abs__split_action_bar=0x7f040024; - public static int abs__textButton=0x7f040013; - public static int abs__title=0x7f04001b; - public static int abs__titleDivider=0x7f04001c; - public static int abs__up=0x7f04000b; - public static int disableHome=0x7f040009; - public static int homeAsUp=0x7f040006; - public static int listMode=0x7f040002; - public static int normal=0x7f040001; - public static int showCustom=0x7f040008; - public static int showHome=0x7f040005; - public static int showTitle=0x7f040007; - public static int tabMode=0x7f040003; - public static int useLogo=0x7f040004; - public static int wrap_content=0x7f040000; - } - public static final class integer { - public static int abs__max_action_buttons=0x7f080000; - } - public static final class layout { - public static int abs__action_bar_home=0x7f030000; - public static int abs__action_bar_tab=0x7f030001; - public static int abs__action_bar_tab_bar_view=0x7f030002; - public static int abs__action_bar_title_item=0x7f030003; - public static int abs__action_menu_item_layout=0x7f030004; - public static int abs__action_menu_layout=0x7f030005; - public static int abs__action_mode_bar=0x7f030006; - public static int abs__action_mode_close_item=0x7f030007; - public static int abs__activity_chooser_view=0x7f030008; - public static int abs__activity_chooser_view_list_item=0x7f030009; - public static int abs__dialog_title_holo=0x7f03000a; - public static int abs__list_menu_item_checkbox=0x7f03000b; - public static int abs__list_menu_item_icon=0x7f03000c; - public static int abs__list_menu_item_layout=0x7f03000d; - public static int abs__list_menu_item_radio=0x7f03000e; - public static int abs__popup_menu_item_layout=0x7f03000f; - public static int abs__screen_action_bar=0x7f030010; - public static int abs__screen_action_bar_overlay=0x7f030011; - public static int abs__screen_simple=0x7f030012; - public static int abs__screen_simple_overlay_action_mode=0x7f030013; - public static int main=0x7f030014; - public static int sherlock_spinner_dropdown_item=0x7f030015; - public static int sherlock_spinner_item=0x7f030016; - } - public static final class string { - /** Content description for the action bar "home" affordance. [CHAR LIMIT=NONE] - */ - public static int abs__action_bar_home_description=0x7f090000; - /** Content description for the action bar "up" affordance. [CHAR LIMIT=NONE] - */ - public static int abs__action_bar_up_description=0x7f090001; - /** Content description for the action menu overflow button. [CHAR LIMIT=NONE] - */ - public static int abs__action_menu_overflow_description=0x7f090002; - /** Label for the "Done" button on the far left of action mode toolbars. - */ - public static int abs__action_mode_done=0x7f090003; - /** Title default for a dialog showing possible activities in ActivityChooserView [CHAR LIMIT=25] - */ - public static int abs__activity_chooser_view_dialog_title_default=0x7f090005; - /** Title for a button to expand the list of activities in ActivityChooserView [CHAR LIMIT=25] - */ - public static int abs__activity_chooser_view_see_all=0x7f090004; - /** Description of the shwoing of a popup window with activities to choose from. [CHAR LIMIT=NONE] - */ - public static int abs__activitychooserview_choose_application=0x7f090007; - /** Title for a dialog showing possible activities for sharing in ShareActionProvider [CHAR LIMIT=25] - */ - public static int abs__share_action_provider_share_with=0x7f090006; - /** Description of the choose target button in a ShareActionProvider (share UI). [CHAR LIMIT=NONE] - */ - public static int abs__shareactionprovider_share_with=0x7f090008; - /** Description of a share target (both in the list of such or the default share button) in a ShareActionProvider (share UI). [CHAR LIMIT=NONE] - */ - public static int abs__shareactionprovider_share_with_application=0x7f090009; - public static int app_name=0x7f09000b; - public static int hello=0x7f09000a; - } - public static final class style { - public static int DialogWindowTitle_Sherlock=0x7f0a0033; - public static int DialogWindowTitle_Sherlock_Light=0x7f0a0034; - public static int Sherlock___TextAppearance_Small=0x7f0a0047; - public static int Sherlock___Theme=0x7f0a004a; - public static int Sherlock___Theme_DarkActionBar=0x7f0a004c; - public static int Sherlock___Theme_Dialog=0x7f0a004d; - public static int Sherlock___Theme_Light=0x7f0a004b; - public static int Sherlock___Widget_ActionBar=0x7f0a0001; - public static int Sherlock___Widget_ActionMode=0x7f0a0016; - public static int Sherlock___Widget_ActivityChooserView=0x7f0a001e; - public static int Sherlock___Widget_Holo_DropDownItem=0x7f0a0029; - public static int Sherlock___Widget_Holo_ListView=0x7f0a0026; - public static int Sherlock___Widget_Holo_Spinner=0x7f0a0023; - public static int TextAppearance_Sherlock_DialogWindowTitle=0x7f0a0045; - public static int TextAppearance_Sherlock_Light_DialogWindowTitle=0x7f0a0046; - public static int TextAppearance_Sherlock_Light_Small=0x7f0a0049; - public static int TextAppearance_Sherlock_Light_Widget_PopupMenu_Large=0x7f0a0040; - public static int TextAppearance_Sherlock_Light_Widget_PopupMenu_Small=0x7f0a0042; - public static int TextAppearance_Sherlock_Small=0x7f0a0048; - public static int TextAppearance_Sherlock_Widget_ActionBar_Menu=0x7f0a0035; - public static int TextAppearance_Sherlock_Widget_ActionBar_Subtitle=0x7f0a0038; - public static int TextAppearance_Sherlock_Widget_ActionBar_Subtitle_Inverse=0x7f0a0039; - public static int TextAppearance_Sherlock_Widget_ActionBar_Title=0x7f0a0036; - public static int TextAppearance_Sherlock_Widget_ActionBar_Title_Inverse=0x7f0a0037; - public static int TextAppearance_Sherlock_Widget_ActionMode_Subtitle=0x7f0a003c; - public static int TextAppearance_Sherlock_Widget_ActionMode_Subtitle_Inverse=0x7f0a003d; - public static int TextAppearance_Sherlock_Widget_ActionMode_Title=0x7f0a003a; - public static int TextAppearance_Sherlock_Widget_ActionMode_Title_Inverse=0x7f0a003b; - public static int TextAppearance_Sherlock_Widget_DropDownItem=0x7f0a0044; - public static int TextAppearance_Sherlock_Widget_PopupMenu=0x7f0a003e; - public static int TextAppearance_Sherlock_Widget_PopupMenu_Large=0x7f0a003f; - public static int TextAppearance_Sherlock_Widget_PopupMenu_Small=0x7f0a0041; - public static int TextAppearance_Sherlock_Widget_TextView_SpinnerItem=0x7f0a0043; - public static int Theme_Sherlock=0x7f0a004e; - public static int Theme_Sherlock_Dialog=0x7f0a0056; - public static int Theme_Sherlock_ForceOverflow=0x7f0a0053; - public static int Theme_Sherlock_Light=0x7f0a004f; - public static int Theme_Sherlock_Light_DarkActionBar=0x7f0a0050; - public static int Theme_Sherlock_Light_DarkActionBar_ForceOverflow=0x7f0a0055; - public static int Theme_Sherlock_Light_Dialog=0x7f0a0057; - public static int Theme_Sherlock_Light_ForceOverflow=0x7f0a0054; - public static int Theme_Sherlock_Light_NoActionBar=0x7f0a0052; - public static int Theme_Sherlock_NoActionBar=0x7f0a0051; - public static int Widget=0x7f0a0000; - public static int Widget_Sherlock_ActionBar=0x7f0a0002; - public static int Widget_Sherlock_ActionBar_Solid=0x7f0a0003; - public static int Widget_Sherlock_ActionBar_TabBar=0x7f0a000a; - public static int Widget_Sherlock_ActionBar_TabText=0x7f0a000d; - public static int Widget_Sherlock_ActionBar_TabView=0x7f0a0007; - public static int Widget_Sherlock_ActionButton=0x7f0a0010; - public static int Widget_Sherlock_ActionButton_CloseMode=0x7f0a0012; - public static int Widget_Sherlock_ActionButton_Overflow=0x7f0a0014; - public static int Widget_Sherlock_ActionMode=0x7f0a0017; - public static int Widget_Sherlock_ActivityChooserView=0x7f0a001f; - public static int Widget_Sherlock_Button_Small=0x7f0a0021; - public static int Widget_Sherlock_DropDownItem_Spinner=0x7f0a002a; - public static int Widget_Sherlock_Light_ActionBar=0x7f0a0004; - public static int Widget_Sherlock_Light_ActionBar_Solid=0x7f0a0005; - public static int Widget_Sherlock_Light_ActionBar_Solid_Inverse=0x7f0a0006; - public static int Widget_Sherlock_Light_ActionBar_TabBar=0x7f0a000b; - public static int Widget_Sherlock_Light_ActionBar_TabBar_Inverse=0x7f0a000c; - public static int Widget_Sherlock_Light_ActionBar_TabText=0x7f0a000e; - public static int Widget_Sherlock_Light_ActionBar_TabText_Inverse=0x7f0a000f; - public static int Widget_Sherlock_Light_ActionBar_TabView=0x7f0a0008; - public static int Widget_Sherlock_Light_ActionBar_TabView_Inverse=0x7f0a0009; - public static int Widget_Sherlock_Light_ActionButton=0x7f0a0011; - public static int Widget_Sherlock_Light_ActionButton_CloseMode=0x7f0a0013; - public static int Widget_Sherlock_Light_ActionButton_Overflow=0x7f0a0015; - public static int Widget_Sherlock_Light_ActionMode=0x7f0a0018; - public static int Widget_Sherlock_Light_ActionMode_Inverse=0x7f0a0019; - public static int Widget_Sherlock_Light_ActivityChooserView=0x7f0a0020; - public static int Widget_Sherlock_Light_Button_Small=0x7f0a0022; - public static int Widget_Sherlock_Light_DropDownItem_Spinner=0x7f0a002b; - public static int Widget_Sherlock_Light_ListPopupWindow=0x7f0a001b; - public static int Widget_Sherlock_Light_ListView_DropDown=0x7f0a0028; - public static int Widget_Sherlock_Light_PopupMenu=0x7f0a001d; - public static int Widget_Sherlock_Light_PopupWindow_ActionMode=0x7f0a002d; - public static int Widget_Sherlock_Light_ProgressBar=0x7f0a002f; - public static int Widget_Sherlock_Light_ProgressBar_Horizontal=0x7f0a0031; - public static int Widget_Sherlock_Light_Spinner_DropDown_ActionBar=0x7f0a0025; - public static int Widget_Sherlock_ListPopupWindow=0x7f0a001a; - public static int Widget_Sherlock_ListView_DropDown=0x7f0a0027; - public static int Widget_Sherlock_PopupMenu=0x7f0a001c; - public static int Widget_Sherlock_PopupWindow_ActionMode=0x7f0a002c; - public static int Widget_Sherlock_ProgressBar=0x7f0a002e; - public static int Widget_Sherlock_ProgressBar_Horizontal=0x7f0a0030; - public static int Widget_Sherlock_Spinner_DropDown_ActionBar=0x7f0a0024; - public static int Widget_Sherlock_TextView_SpinnerItem=0x7f0a0032; - } - public static final class styleable { - /** Attributes used to style the Action Bar. -

Includes the following attributes:

- - - - - - - - - - - - - - - - - - - - - - - -
AttributeDescription
{@link #SherlockActionBar_background com.actionbarsherlock:background} Specifies a background drawable for the action bar.
{@link #SherlockActionBar_backgroundSplit com.actionbarsherlock:backgroundSplit} Specifies a background drawable for the bottom component of a split action bar.
{@link #SherlockActionBar_backgroundStacked com.actionbarsherlock:backgroundStacked} Specifies a background drawable for a second stacked row of the action bar.
{@link #SherlockActionBar_customNavigationLayout com.actionbarsherlock:customNavigationLayout} Specifies a layout for custom navigation.
{@link #SherlockActionBar_displayOptions com.actionbarsherlock:displayOptions} Options affecting how the action bar is displayed.
{@link #SherlockActionBar_divider com.actionbarsherlock:divider} Specifies the drawable used for item dividers.
{@link #SherlockActionBar_height com.actionbarsherlock:height} Specifies a fixed height.
{@link #SherlockActionBar_homeLayout com.actionbarsherlock:homeLayout} Specifies a layout to use for the "home" section of the action bar.
{@link #SherlockActionBar_icon com.actionbarsherlock:icon} Specifies the drawable used for the application icon.
{@link #SherlockActionBar_indeterminateProgressStyle com.actionbarsherlock:indeterminateProgressStyle} Specifies a style resource to use for an indeterminate progress spinner.
{@link #SherlockActionBar_itemPadding com.actionbarsherlock:itemPadding} Specifies padding that should be applied to the left and right sides of - system-provided items in the bar.
{@link #SherlockActionBar_logo com.actionbarsherlock:logo} Specifies the drawable used for the application logo.
{@link #SherlockActionBar_navigationMode com.actionbarsherlock:navigationMode} The type of navigation to use.
{@link #SherlockActionBar_progressBarPadding com.actionbarsherlock:progressBarPadding} Specifies the horizontal padding on either end for an embedded progress bar.
{@link #SherlockActionBar_progressBarStyle com.actionbarsherlock:progressBarStyle} Specifies a style resource to use for an embedded progress bar.
{@link #SherlockActionBar_subtitle com.actionbarsherlock:subtitle} Specifies subtitle text used for navigationMode="normal"
{@link #SherlockActionBar_subtitleTextStyle com.actionbarsherlock:subtitleTextStyle} Specifies a style to use for subtitle text.
{@link #SherlockActionBar_title com.actionbarsherlock:title} Specifies title text used for navigationMode="normal"
{@link #SherlockActionBar_titleTextStyle com.actionbarsherlock:titleTextStyle} Specifies a style to use for title text.
- @see #SherlockActionBar_background - @see #SherlockActionBar_backgroundSplit - @see #SherlockActionBar_backgroundStacked - @see #SherlockActionBar_customNavigationLayout - @see #SherlockActionBar_displayOptions - @see #SherlockActionBar_divider - @see #SherlockActionBar_height - @see #SherlockActionBar_homeLayout - @see #SherlockActionBar_icon - @see #SherlockActionBar_indeterminateProgressStyle - @see #SherlockActionBar_itemPadding - @see #SherlockActionBar_logo - @see #SherlockActionBar_navigationMode - @see #SherlockActionBar_progressBarPadding - @see #SherlockActionBar_progressBarStyle - @see #SherlockActionBar_subtitle - @see #SherlockActionBar_subtitleTextStyle - @see #SherlockActionBar_title - @see #SherlockActionBar_titleTextStyle - */ - public static final int[] SherlockActionBar = { - 0x7f010000, 0x7f010001, 0x7f010002, 0x7f010003, - 0x7f010004, 0x7f010005, 0x7f01003a, 0x7f01003b, - 0x7f01003c, 0x7f01003d, 0x7f01003e, 0x7f01003f, - 0x7f010040, 0x7f010041, 0x7f010042, 0x7f010043, - 0x7f010044, 0x7f010045, 0x7f010046 - }; - /** -

- @attr description - Specifies a background drawable for the action bar. - - -

May be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

May be a color value, in the form of "#rgb", "#argb", -"#rrggbb", or "#aarrggbb". -

This is a private symbol. - @attr name android:background - */ - public static final int SherlockActionBar_background = 2; - /** -

- @attr description - Specifies a background drawable for the bottom component of a split action bar. - - -

May be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

May be a color value, in the form of "#rgb", "#argb", -"#rrggbb", or "#aarrggbb". -

This is a private symbol. - @attr name android:backgroundSplit - */ - public static final int SherlockActionBar_backgroundSplit = 3; - /** -

- @attr description - Specifies a background drawable for a second stacked row of the action bar. - - -

May be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

May be a color value, in the form of "#rgb", "#argb", -"#rrggbb", or "#aarrggbb". -

This is a private symbol. - @attr name android:backgroundStacked - */ - public static final int SherlockActionBar_backgroundStacked = 12; - /** -

- @attr description - Specifies a layout for custom navigation. Overrides navigationMode. - - -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

This is a private symbol. - @attr name android:customNavigationLayout - */ - public static final int SherlockActionBar_customNavigationLayout = 13; - /** -

- @attr description - Options affecting how the action bar is displayed. - - -

Must be one or more (separated by '|') of the following constant values.

- ---- - - - - - - -
ConstantValueDescription
useLogo0x1
showHome0x2
homeAsUp0x4
showTitle0x8
showCustom0x10
disableHome0x20
-

This is a private symbol. - @attr name android:displayOptions - */ - public static final int SherlockActionBar_displayOptions = 7; - /** -

- @attr description - Specifies the drawable used for item dividers. - - -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

This is a private symbol. - @attr name android:divider - */ - public static final int SherlockActionBar_divider = 5; - /** -

- @attr description - Specifies a fixed height. - - -

Must be a dimension value, which is a floating point number appended with a unit such as "14.5sp". -Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size), -in (inches), mm (millimeters). -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. -

This is a private symbol. - @attr name android:height - */ - public static final int SherlockActionBar_height = 4; - /** -

- @attr description - Specifies a layout to use for the "home" section of the action bar. - - -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

This is a private symbol. - @attr name android:homeLayout - */ - public static final int SherlockActionBar_homeLayout = 14; - /** -

- @attr description - Specifies the drawable used for the application icon. - - -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

This is a private symbol. - @attr name android:icon - */ - public static final int SherlockActionBar_icon = 10; - /** -

- @attr description - Specifies a style resource to use for an indeterminate progress spinner. - - -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

This is a private symbol. - @attr name android:indeterminateProgressStyle - */ - public static final int SherlockActionBar_indeterminateProgressStyle = 16; - /** -

- @attr description - Specifies padding that should be applied to the left and right sides of - system-provided items in the bar. - - -

Must be a dimension value, which is a floating point number appended with a unit such as "14.5sp". -Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size), -in (inches), mm (millimeters). -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. -

This is a private symbol. - @attr name android:itemPadding - */ - public static final int SherlockActionBar_itemPadding = 18; - /** -

- @attr description - Specifies the drawable used for the application logo. - - -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

This is a private symbol. - @attr name android:logo - */ - public static final int SherlockActionBar_logo = 11; - /** -

- @attr description - The type of navigation to use. - - -

Must be one of the following constant values.

- ---- - - - -
ConstantValueDescription
normal0 Normal static title text
listMode1 The action bar will use a selection list for navigation.
tabMode2 The action bar will use a series of horizontal tabs for navigation.
-

This is a private symbol. - @attr name android:navigationMode - */ - public static final int SherlockActionBar_navigationMode = 6; - /** -

- @attr description - Specifies the horizontal padding on either end for an embedded progress bar. - - -

Must be a dimension value, which is a floating point number appended with a unit such as "14.5sp". -Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size), -in (inches), mm (millimeters). -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. -

This is a private symbol. - @attr name android:progressBarPadding - */ - public static final int SherlockActionBar_progressBarPadding = 17; - /** -

- @attr description - Specifies a style resource to use for an embedded progress bar. - - -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

This is a private symbol. - @attr name android:progressBarStyle - */ - public static final int SherlockActionBar_progressBarStyle = 15; - /** -

- @attr description - Specifies subtitle text used for navigationMode="normal" - - -

Must be a string value, using '\\;' to escape characters such as '\\n' or '\\uxxxx' for a unicode character. -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. -

This is a private symbol. - @attr name android:subtitle - */ - public static final int SherlockActionBar_subtitle = 9; - /** -

- @attr description - Specifies a style to use for subtitle text. - - -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

This is a private symbol. - @attr name android:subtitleTextStyle - */ - public static final int SherlockActionBar_subtitleTextStyle = 1; - /** -

- @attr description - Specifies title text used for navigationMode="normal" - - -

Must be a string value, using '\\;' to escape characters such as '\\n' or '\\uxxxx' for a unicode character. -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. -

This is a private symbol. - @attr name android:title - */ - public static final int SherlockActionBar_title = 8; - /** -

- @attr description - Specifies a style to use for title text. - - -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

This is a private symbol. - @attr name android:titleTextStyle - */ - public static final int SherlockActionBar_titleTextStyle = 0; - /** Attributes that can be used with a SherlockActionMenuItemView. -

Includes the following attributes:

- - - - - -
AttributeDescription
{@link #SherlockActionMenuItemView_android_minWidth com.actionbarsherlock:android_minWidth}
- @see #SherlockActionMenuItemView_android_minWidth - */ - public static final int[] SherlockActionMenuItemView = { - 0x0101013f - }; - /** -

This symbol is the offset where the {@link com.actionbarsherlock.R.attr#android_minWidth} - attribute's value can be found in the {@link #SherlockActionMenuItemView} array. - @attr name android:android_minWidth - */ - public static final int SherlockActionMenuItemView_android_minWidth = 0; - /** Attributes that can be used with a SherlockActionMode. -

Includes the following attributes:

- - - - - - - - - -
AttributeDescription
{@link #SherlockActionMode_background com.actionbarsherlock:background} Specifies a background for the action mode bar.
{@link #SherlockActionMode_backgroundSplit com.actionbarsherlock:backgroundSplit} Specifies a background for the split action mode bar.
{@link #SherlockActionMode_height com.actionbarsherlock:height} Specifies a fixed height for the action mode bar.
{@link #SherlockActionMode_subtitleTextStyle com.actionbarsherlock:subtitleTextStyle} Specifies a style to use for subtitle text.
{@link #SherlockActionMode_titleTextStyle com.actionbarsherlock:titleTextStyle} Specifies a style to use for title text.
- @see #SherlockActionMode_background - @see #SherlockActionMode_backgroundSplit - @see #SherlockActionMode_height - @see #SherlockActionMode_subtitleTextStyle - @see #SherlockActionMode_titleTextStyle - */ - public static final int[] SherlockActionMode = { - 0x7f010000, 0x7f010001, 0x7f010002, 0x7f010003, - 0x7f010004 - }; - /** -

- @attr description - Specifies a background for the action mode bar. - - -

May be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

May be a color value, in the form of "#rgb", "#argb", -"#rrggbb", or "#aarrggbb". -

This is a private symbol. - @attr name android:background - */ - public static final int SherlockActionMode_background = 2; - /** -

- @attr description - Specifies a background for the split action mode bar. - - -

May be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

May be a color value, in the form of "#rgb", "#argb", -"#rrggbb", or "#aarrggbb". -

This is a private symbol. - @attr name android:backgroundSplit - */ - public static final int SherlockActionMode_backgroundSplit = 3; - /** -

- @attr description - Specifies a fixed height for the action mode bar. - - -

Must be a dimension value, which is a floating point number appended with a unit such as "14.5sp". -Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size), -in (inches), mm (millimeters). -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. -

This is a private symbol. - @attr name android:height - */ - public static final int SherlockActionMode_height = 4; - /** -

- @attr description - Specifies a style to use for subtitle text. - - -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

This is a private symbol. - @attr name android:subtitleTextStyle - */ - public static final int SherlockActionMode_subtitleTextStyle = 1; - /** -

- @attr description - Specifies a style to use for title text. - - -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

This is a private symbol. - @attr name android:titleTextStyle - */ - public static final int SherlockActionMode_titleTextStyle = 0; - /** Attributes that can be used with a SherlockActivityChooserView. -

Includes the following attributes:

- - - - - - - -
AttributeDescription
{@link #SherlockActivityChooserView_android_background com.actionbarsherlock:android_background}
{@link #SherlockActivityChooserView_expandActivityOverflowButtonDrawable com.actionbarsherlock:expandActivityOverflowButtonDrawable} The drawable to show in the button for expanding the activities overflow popup.
{@link #SherlockActivityChooserView_initialActivityCount com.actionbarsherlock:initialActivityCount} The maximal number of items initially shown in the activity list.
- @see #SherlockActivityChooserView_android_background - @see #SherlockActivityChooserView_expandActivityOverflowButtonDrawable - @see #SherlockActivityChooserView_initialActivityCount - */ - public static final int[] SherlockActivityChooserView = { - 0x010100d4, 0x7f01004f, 0x7f010050 - }; - /** -

This symbol is the offset where the {@link com.actionbarsherlock.R.attr#android_background} - attribute's value can be found in the {@link #SherlockActivityChooserView} array. - @attr name android:android_background - */ - public static final int SherlockActivityChooserView_android_background = 0; - /** -

- @attr description - The drawable to show in the button for expanding the activities overflow popup. - Note: Clients would like to set this drawable - as a clue about the action the chosen activity will perform. For - example, if share activity is to be chosen the drawable should - give a clue that sharing is to be performed. - - - -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

This is a private symbol. - @attr name android:expandActivityOverflowButtonDrawable - */ - public static final int SherlockActivityChooserView_expandActivityOverflowButtonDrawable = 2; - /** -

- @attr description - The maximal number of items initially shown in the activity list. - - -

Must be a string value, using '\\;' to escape characters such as '\\n' or '\\uxxxx' for a unicode character. -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. -

This is a private symbol. - @attr name android:initialActivityCount - */ - public static final int SherlockActivityChooserView_initialActivityCount = 1; - /** Base attributes that are available to all groups. -

Includes the following attributes:

- - - - - - - - - - -
AttributeDescription
{@link #SherlockMenuGroup_android_checkableBehavior com.actionbarsherlock:android_checkableBehavior} Whether the items are capable of displaying a check mark.
{@link #SherlockMenuGroup_android_enabled com.actionbarsherlock:android_enabled} Whether the items are enabled.
{@link #SherlockMenuGroup_android_id com.actionbarsherlock:android_id} The ID of the group.
{@link #SherlockMenuGroup_android_menuCategory com.actionbarsherlock:android_menuCategory} The category applied to all items within this group.
{@link #SherlockMenuGroup_android_orderInCategory com.actionbarsherlock:android_orderInCategory} The order within the category applied to all items within this group.
{@link #SherlockMenuGroup_android_visible com.actionbarsherlock:android_visible} Whether the items are shown/visible.
- @see #SherlockMenuGroup_android_checkableBehavior - @see #SherlockMenuGroup_android_enabled - @see #SherlockMenuGroup_android_id - @see #SherlockMenuGroup_android_menuCategory - @see #SherlockMenuGroup_android_orderInCategory - @see #SherlockMenuGroup_android_visible - */ - public static final int[] SherlockMenuGroup = { - 0x0101000e, 0x010100d0, 0x01010194, 0x010101de, - 0x010101df, 0x010101e0 - }; - /** -

- @attr description - Whether the items are capable of displaying a check mark. -

This corresponds to the global attribute resource symbol {@link com.actionbarsherlock.R.attr#android_checkableBehavior}. - @attr name android:android_checkableBehavior - */ - public static final int SherlockMenuGroup_android_checkableBehavior = 5; - /** -

- @attr description - Whether the items are enabled. -

This corresponds to the global attribute resource symbol {@link com.actionbarsherlock.R.attr#android_enabled}. - @attr name android:android_enabled - */ - public static final int SherlockMenuGroup_android_enabled = 0; - /** -

- @attr description - The ID of the group. -

This corresponds to the global attribute resource symbol {@link com.actionbarsherlock.R.attr#android_id}. - @attr name android:android_id - */ - public static final int SherlockMenuGroup_android_id = 1; - /** -

- @attr description - The category applied to all items within this group. - (This will be or'ed with the orderInCategory attribute.) -

This corresponds to the global attribute resource symbol {@link com.actionbarsherlock.R.attr#android_menuCategory}. - @attr name android:android_menuCategory - */ - public static final int SherlockMenuGroup_android_menuCategory = 3; - /** -

- @attr description - The order within the category applied to all items within this group. - (This will be or'ed with the category attribute.) -

This corresponds to the global attribute resource symbol {@link com.actionbarsherlock.R.attr#android_orderInCategory}. - @attr name android:android_orderInCategory - */ - public static final int SherlockMenuGroup_android_orderInCategory = 4; - /** -

- @attr description - Whether the items are shown/visible. -

This corresponds to the global attribute resource symbol {@link com.actionbarsherlock.R.attr#android_visible}. - @attr name android:android_visible - */ - public static final int SherlockMenuGroup_android_visible = 2; - /** Base attributes that are available to all Item objects. -

Includes the following attributes:

- - - - - - - - - - - - - - - - - - - - - -
AttributeDescription
{@link #SherlockMenuItem_android_actionLayout com.actionbarsherlock:android_actionLayout} An optional layout to be used as an action view.
{@link #SherlockMenuItem_android_actionProviderClass com.actionbarsherlock:android_actionProviderClass} The name of an optional ActionProvider class to instantiate an action view - and perform operations such as default action for that menu item.
{@link #SherlockMenuItem_android_actionViewClass com.actionbarsherlock:android_actionViewClass} The name of an optional View class to instantiate and use as an - action view.
{@link #SherlockMenuItem_android_alphabeticShortcut com.actionbarsherlock:android_alphabeticShortcut} The alphabetic shortcut key.
{@link #SherlockMenuItem_android_checkable com.actionbarsherlock:android_checkable} Whether the item is capable of displaying a check mark.
{@link #SherlockMenuItem_android_checked com.actionbarsherlock:android_checked} Whether the item is checked.
{@link #SherlockMenuItem_android_enabled com.actionbarsherlock:android_enabled} Whether the item is enabled.
{@link #SherlockMenuItem_android_icon com.actionbarsherlock:android_icon} The icon associated with this item.
{@link #SherlockMenuItem_android_id com.actionbarsherlock:android_id} The ID of the item.
{@link #SherlockMenuItem_android_menuCategory com.actionbarsherlock:android_menuCategory} The category applied to the item.
{@link #SherlockMenuItem_android_numericShortcut com.actionbarsherlock:android_numericShortcut} The numeric shortcut key.
{@link #SherlockMenuItem_android_onClick com.actionbarsherlock:android_onClick} Name of a method on the Context used to inflate the menu that will be - called when the item is clicked.
{@link #SherlockMenuItem_android_orderInCategory com.actionbarsherlock:android_orderInCategory} The order within the category applied to the item.
{@link #SherlockMenuItem_android_showAsAction com.actionbarsherlock:android_showAsAction} How this item should display in the Action Bar, if present.
{@link #SherlockMenuItem_android_title com.actionbarsherlock:android_title} The title associated with the item.
{@link #SherlockMenuItem_android_titleCondensed com.actionbarsherlock:android_titleCondensed} The condensed title associated with the item.
{@link #SherlockMenuItem_android_visible com.actionbarsherlock:android_visible} Whether the item is shown/visible.
- @see #SherlockMenuItem_android_actionLayout - @see #SherlockMenuItem_android_actionProviderClass - @see #SherlockMenuItem_android_actionViewClass - @see #SherlockMenuItem_android_alphabeticShortcut - @see #SherlockMenuItem_android_checkable - @see #SherlockMenuItem_android_checked - @see #SherlockMenuItem_android_enabled - @see #SherlockMenuItem_android_icon - @see #SherlockMenuItem_android_id - @see #SherlockMenuItem_android_menuCategory - @see #SherlockMenuItem_android_numericShortcut - @see #SherlockMenuItem_android_onClick - @see #SherlockMenuItem_android_orderInCategory - @see #SherlockMenuItem_android_showAsAction - @see #SherlockMenuItem_android_title - @see #SherlockMenuItem_android_titleCondensed - @see #SherlockMenuItem_android_visible - */ - public static final int[] SherlockMenuItem = { - 0x01010002, 0x0101000e, 0x010100d0, 0x01010106, - 0x01010194, 0x010101de, 0x010101df, 0x010101e1, - 0x010101e2, 0x010101e3, 0x010101e4, 0x010101e5, - 0x0101026f, 0x010102d9, 0x010102fb, 0x010102fc, - 0x01010389 - }; - /** -

- @attr description - An optional layout to be used as an action view. - See {@link android.view.MenuItem#setActionView(android.view.View)} - for more info. -

This corresponds to the global attribute resource symbol {@link com.actionbarsherlock.R.attr#android_actionLayout}. - @attr name android:android_actionLayout - */ - public static final int SherlockMenuItem_android_actionLayout = 14; - /** -

- @attr description - The name of an optional ActionProvider class to instantiate an action view - and perform operations such as default action for that menu item. - See {@link android.view.MenuItem#setActionProvider(android.view.ActionProvider)} - for more info. -

This corresponds to the global attribute resource symbol {@link com.actionbarsherlock.R.attr#android_actionProviderClass}. - @attr name android:android_actionProviderClass - */ - public static final int SherlockMenuItem_android_actionProviderClass = 16; - /** -

- @attr description - The name of an optional View class to instantiate and use as an - action view. See {@link android.view.MenuItem#setActionView(android.view.View)} - for more info. -

This corresponds to the global attribute resource symbol {@link com.actionbarsherlock.R.attr#android_actionViewClass}. - @attr name android:android_actionViewClass - */ - public static final int SherlockMenuItem_android_actionViewClass = 15; - /** -

- @attr description - The alphabetic shortcut key. This is the shortcut when using a keyboard - with alphabetic keys. -

This corresponds to the global attribute resource symbol {@link com.actionbarsherlock.R.attr#android_alphabeticShortcut}. - @attr name android:android_alphabeticShortcut - */ - public static final int SherlockMenuItem_android_alphabeticShortcut = 9; - /** -

- @attr description - Whether the item is capable of displaying a check mark. -

This corresponds to the global attribute resource symbol {@link com.actionbarsherlock.R.attr#android_checkable}. - @attr name android:android_checkable - */ - public static final int SherlockMenuItem_android_checkable = 11; - /** -

- @attr description - Whether the item is checked. Note that you must first have enabled checking with - the checkable attribute or else the check mark will not appear. -

This corresponds to the global attribute resource symbol {@link com.actionbarsherlock.R.attr#android_checked}. - @attr name android:android_checked - */ - public static final int SherlockMenuItem_android_checked = 3; - /** -

- @attr description - Whether the item is enabled. -

This corresponds to the global attribute resource symbol {@link com.actionbarsherlock.R.attr#android_enabled}. - @attr name android:android_enabled - */ - public static final int SherlockMenuItem_android_enabled = 1; - /** -

- @attr description - The icon associated with this item. This icon will not always be shown, so - the title should be sufficient in describing this item. -

This corresponds to the global attribute resource symbol {@link com.actionbarsherlock.R.attr#android_icon}. - @attr name android:android_icon - */ - public static final int SherlockMenuItem_android_icon = 0; - /** -

- @attr description - The ID of the item. -

This corresponds to the global attribute resource symbol {@link com.actionbarsherlock.R.attr#android_id}. - @attr name android:android_id - */ - public static final int SherlockMenuItem_android_id = 2; - /** -

- @attr description - The category applied to the item. - (This will be or'ed with the orderInCategory attribute.) -

This corresponds to the global attribute resource symbol {@link com.actionbarsherlock.R.attr#android_menuCategory}. - @attr name android:android_menuCategory - */ - public static final int SherlockMenuItem_android_menuCategory = 5; - /** -

- @attr description - The numeric shortcut key. This is the shortcut when using a numeric (e.g., 12-key) - keyboard. -

This corresponds to the global attribute resource symbol {@link com.actionbarsherlock.R.attr#android_numericShortcut}. - @attr name android:android_numericShortcut - */ - public static final int SherlockMenuItem_android_numericShortcut = 10; - /** -

- @attr description - Name of a method on the Context used to inflate the menu that will be - called when the item is clicked. -

This corresponds to the global attribute resource symbol {@link com.actionbarsherlock.R.attr#android_onClick}. - @attr name android:android_onClick - */ - public static final int SherlockMenuItem_android_onClick = 12; - /** -

- @attr description - The order within the category applied to the item. - (This will be or'ed with the category attribute.) -

This corresponds to the global attribute resource symbol {@link com.actionbarsherlock.R.attr#android_orderInCategory}. - @attr name android:android_orderInCategory - */ - public static final int SherlockMenuItem_android_orderInCategory = 6; - /** -

- @attr description - How this item should display in the Action Bar, if present. -

This corresponds to the global attribute resource symbol {@link com.actionbarsherlock.R.attr#android_showAsAction}. - @attr name android:android_showAsAction - */ - public static final int SherlockMenuItem_android_showAsAction = 13; - /** -

- @attr description - The title associated with the item. -

This corresponds to the global attribute resource symbol {@link com.actionbarsherlock.R.attr#android_title}. - @attr name android:android_title - */ - public static final int SherlockMenuItem_android_title = 7; - /** -

- @attr description - The condensed title associated with the item. This is used in situations where the - normal title may be too long to be displayed. -

This corresponds to the global attribute resource symbol {@link com.actionbarsherlock.R.attr#android_titleCondensed}. - @attr name android:android_titleCondensed - */ - public static final int SherlockMenuItem_android_titleCondensed = 8; - /** -

- @attr description - Whether the item is shown/visible. -

This corresponds to the global attribute resource symbol {@link com.actionbarsherlock.R.attr#android_visible}. - @attr name android:android_visible - */ - public static final int SherlockMenuItem_android_visible = 4; - /** Attributes that can be used with a SherlockMenuView. -

Includes the following attributes:

- - - - - - - - - - - - -
AttributeDescription
{@link #SherlockMenuView_headerBackground com.actionbarsherlock:headerBackground} Default background for the menu header.
{@link #SherlockMenuView_horizontalDivider com.actionbarsherlock:horizontalDivider} Default horizontal divider between rows of menu items.
{@link #SherlockMenuView_itemBackground com.actionbarsherlock:itemBackground} Default background for each menu item.
{@link #SherlockMenuView_itemIconDisabledAlpha com.actionbarsherlock:itemIconDisabledAlpha} Default disabled icon alpha for each menu item that shows an icon.
{@link #SherlockMenuView_itemTextAppearance com.actionbarsherlock:itemTextAppearance} Default appearance of menu item text.
{@link #SherlockMenuView_preserveIconSpacing com.actionbarsherlock:preserveIconSpacing} Whether space should be reserved in layout when an icon is missing.
{@link #SherlockMenuView_verticalDivider com.actionbarsherlock:verticalDivider} Default vertical divider between menu items.
{@link #SherlockMenuView_windowAnimationStyle com.actionbarsherlock:windowAnimationStyle} Default animations for the menu.
- @see #SherlockMenuView_headerBackground - @see #SherlockMenuView_horizontalDivider - @see #SherlockMenuView_itemBackground - @see #SherlockMenuView_itemIconDisabledAlpha - @see #SherlockMenuView_itemTextAppearance - @see #SherlockMenuView_preserveIconSpacing - @see #SherlockMenuView_verticalDivider - @see #SherlockMenuView_windowAnimationStyle - */ - public static final int[] SherlockMenuView = { - 0x7f010047, 0x7f010048, 0x7f010049, 0x7f01004a, - 0x7f01004b, 0x7f01004c, 0x7f01004d, 0x7f01004e - }; - /** -

- @attr description - Default background for the menu header. - - -

May be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

May be a color value, in the form of "#rgb", "#argb", -"#rrggbb", or "#aarrggbb". -

This is a private symbol. - @attr name android:headerBackground - */ - public static final int SherlockMenuView_headerBackground = 3; - /** -

- @attr description - Default horizontal divider between rows of menu items. - - -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

This is a private symbol. - @attr name android:horizontalDivider - */ - public static final int SherlockMenuView_horizontalDivider = 1; - /** -

- @attr description - Default background for each menu item. - - -

May be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

May be a color value, in the form of "#rgb", "#argb", -"#rrggbb", or "#aarrggbb". -

This is a private symbol. - @attr name android:itemBackground - */ - public static final int SherlockMenuView_itemBackground = 4; - /** -

- @attr description - Default disabled icon alpha for each menu item that shows an icon. - - -

Must be a floating point value, such as "1.2". -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. -

This is a private symbol. - @attr name android:itemIconDisabledAlpha - */ - public static final int SherlockMenuView_itemIconDisabledAlpha = 6; - /** -

- @attr description - Default appearance of menu item text. - - -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

This is a private symbol. - @attr name android:itemTextAppearance - */ - public static final int SherlockMenuView_itemTextAppearance = 0; - /** -

- @attr description - Whether space should be reserved in layout when an icon is missing. - - -

Must be a boolean value, either "true" or "false". -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. -

This is a private symbol. - @attr name android:preserveIconSpacing - */ - public static final int SherlockMenuView_preserveIconSpacing = 7; - /** -

- @attr description - Default vertical divider between menu items. - - -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

This is a private symbol. - @attr name android:verticalDivider - */ - public static final int SherlockMenuView_verticalDivider = 2; - /** -

- @attr description - Default animations for the menu. - - -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

This is a private symbol. - @attr name android:windowAnimationStyle - */ - public static final int SherlockMenuView_windowAnimationStyle = 5; - /** Attributes that can be used with a SherlockSpinner. -

Includes the following attributes:

- - - - - - - - - - - - -
AttributeDescription
{@link #SherlockSpinner_android_dropDownHorizontalOffset com.actionbarsherlock:android_dropDownHorizontalOffset} Horizontal offset from the spinner widget for positioning the dropdown - in spinnerMode="dropdown".
{@link #SherlockSpinner_android_dropDownSelector com.actionbarsherlock:android_dropDownSelector} List selector to use for spinnerMode="dropdown" display.
{@link #SherlockSpinner_android_dropDownVerticalOffset com.actionbarsherlock:android_dropDownVerticalOffset} Vertical offset from the spinner widget for positioning the dropdown in - spinnerMode="dropdown".
{@link #SherlockSpinner_android_dropDownWidth com.actionbarsherlock:android_dropDownWidth} Width of the dropdown in spinnerMode="dropdown".
{@link #SherlockSpinner_android_gravity com.actionbarsherlock:android_gravity} Gravity setting for positioning the currently selected item.
{@link #SherlockSpinner_android_popupBackground com.actionbarsherlock:android_popupBackground} Background drawable to use for the dropdown in spinnerMode="dropdown".
{@link #SherlockSpinner_android_popupPromptView com.actionbarsherlock:android_popupPromptView} Reference to a layout to use for displaying a prompt in the dropdown for - spinnerMode="dropdown".
{@link #SherlockSpinner_android_prompt com.actionbarsherlock:android_prompt} The prompt to display when the spinner's dialog is shown.
- @see #SherlockSpinner_android_dropDownHorizontalOffset - @see #SherlockSpinner_android_dropDownSelector - @see #SherlockSpinner_android_dropDownVerticalOffset - @see #SherlockSpinner_android_dropDownWidth - @see #SherlockSpinner_android_gravity - @see #SherlockSpinner_android_popupBackground - @see #SherlockSpinner_android_popupPromptView - @see #SherlockSpinner_android_prompt - */ - public static final int[] SherlockSpinner = { - 0x010100af, 0x01010175, 0x01010176, 0x0101017b, - 0x01010262, 0x010102ac, 0x010102ad, 0x010103ef - }; - /** -

- @attr description - Horizontal offset from the spinner widget for positioning the dropdown - in spinnerMode="dropdown". -

This corresponds to the global attribute resource symbol {@link com.actionbarsherlock.R.attr#android_dropDownHorizontalOffset}. - @attr name android:android_dropDownHorizontalOffset - */ - public static final int SherlockSpinner_android_dropDownHorizontalOffset = 5; - /** -

- @attr description - List selector to use for spinnerMode="dropdown" display. -

This corresponds to the global attribute resource symbol {@link com.actionbarsherlock.R.attr#android_dropDownSelector}. - @attr name android:android_dropDownSelector - */ - public static final int SherlockSpinner_android_dropDownSelector = 1; - /** -

- @attr description - Vertical offset from the spinner widget for positioning the dropdown in - spinnerMode="dropdown". -

This corresponds to the global attribute resource symbol {@link com.actionbarsherlock.R.attr#android_dropDownVerticalOffset}. - @attr name android:android_dropDownVerticalOffset - */ - public static final int SherlockSpinner_android_dropDownVerticalOffset = 6; - /** -

- @attr description - Width of the dropdown in spinnerMode="dropdown". -

This corresponds to the global attribute resource symbol {@link com.actionbarsherlock.R.attr#android_dropDownWidth}. - @attr name android:android_dropDownWidth - */ - public static final int SherlockSpinner_android_dropDownWidth = 4; - /** -

- @attr description - Gravity setting for positioning the currently selected item. -

This corresponds to the global attribute resource symbol {@link com.actionbarsherlock.R.attr#android_gravity}. - @attr name android:android_gravity - */ - public static final int SherlockSpinner_android_gravity = 0; - /** -

- @attr description - Background drawable to use for the dropdown in spinnerMode="dropdown". -

This corresponds to the global attribute resource symbol {@link com.actionbarsherlock.R.attr#android_popupBackground}. - @attr name android:android_popupBackground - */ - public static final int SherlockSpinner_android_popupBackground = 2; - /** -

- @attr description - Reference to a layout to use for displaying a prompt in the dropdown for - spinnerMode="dropdown". This layout must contain a TextView with the id - @android:id/text1 to be populated with the prompt text. -

This is a private symbol. - @attr name android:android_popupPromptView - */ - public static final int SherlockSpinner_android_popupPromptView = 7; - /** -

- @attr description - The prompt to display when the spinner's dialog is shown. -

This corresponds to the global attribute resource symbol {@link com.actionbarsherlock.R.attr#android_prompt}. - @attr name android:android_prompt - */ - public static final int SherlockSpinner_android_prompt = 3; - /** Attributes that can be used with a SherlockTheme. -

Includes the following attributes:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
AttributeDescription
{@link #SherlockTheme_absForceOverflow com.actionbarsherlock:absForceOverflow} Specified if we are forcing an action item overflow menu.
{@link #SherlockTheme_actionBarDivider com.actionbarsherlock:actionBarDivider} Custom divider drawable to use for elements in the action bar.
{@link #SherlockTheme_actionBarItemBackground com.actionbarsherlock:actionBarItemBackground} Custom item state list drawable background for action bar items.
{@link #SherlockTheme_actionBarSize com.actionbarsherlock:actionBarSize} Size of the Action Bar, including the contextual - bar used to present Action Modes.
{@link #SherlockTheme_actionBarSplitStyle com.actionbarsherlock:actionBarSplitStyle} Reference to a style for the split Action Bar.
{@link #SherlockTheme_actionBarStyle com.actionbarsherlock:actionBarStyle} Reference to a style for the Action Bar
{@link #SherlockTheme_actionBarTabBarStyle com.actionbarsherlock:actionBarTabBarStyle}
{@link #SherlockTheme_actionBarTabStyle com.actionbarsherlock:actionBarTabStyle} Default style for tabs within an action bar
{@link #SherlockTheme_actionBarTabTextStyle com.actionbarsherlock:actionBarTabTextStyle}
{@link #SherlockTheme_actionBarWidgetTheme com.actionbarsherlock:actionBarWidgetTheme} Reference to a theme that should be used to inflate widgets - and layouts destined for the action bar.
{@link #SherlockTheme_actionButtonStyle com.actionbarsherlock:actionButtonStyle}
{@link #SherlockTheme_actionDropDownStyle com.actionbarsherlock:actionDropDownStyle}
{@link #SherlockTheme_actionMenuTextAppearance com.actionbarsherlock:actionMenuTextAppearance} TextAppearance style that will be applied to text that - appears within action menu items.
{@link #SherlockTheme_actionMenuTextColor com.actionbarsherlock:actionMenuTextColor} Color for text that appears within action menu items.
{@link #SherlockTheme_actionModeBackground com.actionbarsherlock:actionModeBackground} Background drawable to use for action mode UI
{@link #SherlockTheme_actionModeCloseButtonStyle com.actionbarsherlock:actionModeCloseButtonStyle}
{@link #SherlockTheme_actionModeCloseDrawable com.actionbarsherlock:actionModeCloseDrawable} Drawable to use for the close action mode button
{@link #SherlockTheme_actionModePopupWindowStyle com.actionbarsherlock:actionModePopupWindowStyle} PopupWindow style to use for action modes when showing as a window overlay.
{@link #SherlockTheme_actionModeShareDrawable com.actionbarsherlock:actionModeShareDrawable} Drawable to use for the Share action button in WebView selection action modes
{@link #SherlockTheme_actionModeSplitBackground com.actionbarsherlock:actionModeSplitBackground} Background drawable to use for action mode UI in the lower split bar
{@link #SherlockTheme_actionModeStyle com.actionbarsherlock:actionModeStyle}
{@link #SherlockTheme_actionOverflowButtonStyle com.actionbarsherlock:actionOverflowButtonStyle}
{@link #SherlockTheme_actionSpinnerItemStyle com.actionbarsherlock:actionSpinnerItemStyle}
{@link #SherlockTheme_activatedBackgroundIndicator com.actionbarsherlock:activatedBackgroundIndicator} Drawable used as a background for activated items.
{@link #SherlockTheme_activityChooserViewStyle com.actionbarsherlock:activityChooserViewStyle} Default ActivityChooserView style.
{@link #SherlockTheme_android_windowIsFloating com.actionbarsherlock:android_windowIsFloating}
{@link #SherlockTheme_buttonStyleSmall com.actionbarsherlock:buttonStyleSmall} Small Button style.
{@link #SherlockTheme_dividerVertical com.actionbarsherlock:dividerVertical} Drawable to use for generic vertical dividers.
{@link #SherlockTheme_dropDownListViewStyle com.actionbarsherlock:dropDownListViewStyle}
{@link #SherlockTheme_dropdownListPreferredItemHeight com.actionbarsherlock:dropdownListPreferredItemHeight}
{@link #SherlockTheme_homeAsUpIndicator com.actionbarsherlock:homeAsUpIndicator}
{@link #SherlockTheme_listPopupWindowStyle com.actionbarsherlock:listPopupWindowStyle}
{@link #SherlockTheme_listPreferredItemHeightSmall com.actionbarsherlock:listPreferredItemHeightSmall} A smaller, sleeker list item height.
{@link #SherlockTheme_listPreferredItemPaddingLeft com.actionbarsherlock:listPreferredItemPaddingLeft} The preferred padding along the left edge of list items.
{@link #SherlockTheme_listPreferredItemPaddingRight com.actionbarsherlock:listPreferredItemPaddingRight} The preferred padding along the right edge of list items.
{@link #SherlockTheme_popupMenuStyle com.actionbarsherlock:popupMenuStyle}
{@link #SherlockTheme_spinnerDropDownItemStyle com.actionbarsherlock:spinnerDropDownItemStyle}
{@link #SherlockTheme_spinnerItemStyle com.actionbarsherlock:spinnerItemStyle}
{@link #SherlockTheme_textAppearanceLargePopupMenu com.actionbarsherlock:textAppearanceLargePopupMenu} Text color, typeface, size, and style for the text inside of a popup menu.
{@link #SherlockTheme_textAppearanceListItemSmall com.actionbarsherlock:textAppearanceListItemSmall} The preferred TextAppearance for the primary text of small list items.
{@link #SherlockTheme_textAppearanceSmall com.actionbarsherlock:textAppearanceSmall} Text color, typeface, size, and style for "small" text.
{@link #SherlockTheme_textAppearanceSmallPopupMenu com.actionbarsherlock:textAppearanceSmallPopupMenu} Text color, typeface, size, and style for small text inside of a popup menu.
{@link #SherlockTheme_textColorPrimary com.actionbarsherlock:textColorPrimary}
{@link #SherlockTheme_textColorPrimaryDisableOnly com.actionbarsherlock:textColorPrimaryDisableOnly}
{@link #SherlockTheme_textColorPrimaryInverse com.actionbarsherlock:textColorPrimaryInverse}
{@link #SherlockTheme_windowActionBar com.actionbarsherlock:windowActionBar}
{@link #SherlockTheme_windowActionBarOverlay com.actionbarsherlock:windowActionBarOverlay}
{@link #SherlockTheme_windowActionModeOverlay com.actionbarsherlock:windowActionModeOverlay}
{@link #SherlockTheme_windowContentOverlay com.actionbarsherlock:windowContentOverlay} This Drawable is overlaid over the foreground of the Window's content area, usually - to place a shadow below the title.
{@link #SherlockTheme_windowMinWidthMajor com.actionbarsherlock:windowMinWidthMajor}
{@link #SherlockTheme_windowMinWidthMinor com.actionbarsherlock:windowMinWidthMinor}
{@link #SherlockTheme_windowNoTitle com.actionbarsherlock:windowNoTitle}
{@link #SherlockTheme_windowSplitActionBar com.actionbarsherlock:windowSplitActionBar}
- @see #SherlockTheme_absForceOverflow - @see #SherlockTheme_actionBarDivider - @see #SherlockTheme_actionBarItemBackground - @see #SherlockTheme_actionBarSize - @see #SherlockTheme_actionBarSplitStyle - @see #SherlockTheme_actionBarStyle - @see #SherlockTheme_actionBarTabBarStyle - @see #SherlockTheme_actionBarTabStyle - @see #SherlockTheme_actionBarTabTextStyle - @see #SherlockTheme_actionBarWidgetTheme - @see #SherlockTheme_actionButtonStyle - @see #SherlockTheme_actionDropDownStyle - @see #SherlockTheme_actionMenuTextAppearance - @see #SherlockTheme_actionMenuTextColor - @see #SherlockTheme_actionModeBackground - @see #SherlockTheme_actionModeCloseButtonStyle - @see #SherlockTheme_actionModeCloseDrawable - @see #SherlockTheme_actionModePopupWindowStyle - @see #SherlockTheme_actionModeShareDrawable - @see #SherlockTheme_actionModeSplitBackground - @see #SherlockTheme_actionModeStyle - @see #SherlockTheme_actionOverflowButtonStyle - @see #SherlockTheme_actionSpinnerItemStyle - @see #SherlockTheme_activatedBackgroundIndicator - @see #SherlockTheme_activityChooserViewStyle - @see #SherlockTheme_android_windowIsFloating - @see #SherlockTheme_buttonStyleSmall - @see #SherlockTheme_dividerVertical - @see #SherlockTheme_dropDownListViewStyle - @see #SherlockTheme_dropdownListPreferredItemHeight - @see #SherlockTheme_homeAsUpIndicator - @see #SherlockTheme_listPopupWindowStyle - @see #SherlockTheme_listPreferredItemHeightSmall - @see #SherlockTheme_listPreferredItemPaddingLeft - @see #SherlockTheme_listPreferredItemPaddingRight - @see #SherlockTheme_popupMenuStyle - @see #SherlockTheme_spinnerDropDownItemStyle - @see #SherlockTheme_spinnerItemStyle - @see #SherlockTheme_textAppearanceLargePopupMenu - @see #SherlockTheme_textAppearanceListItemSmall - @see #SherlockTheme_textAppearanceSmall - @see #SherlockTheme_textAppearanceSmallPopupMenu - @see #SherlockTheme_textColorPrimary - @see #SherlockTheme_textColorPrimaryDisableOnly - @see #SherlockTheme_textColorPrimaryInverse - @see #SherlockTheme_windowActionBar - @see #SherlockTheme_windowActionBarOverlay - @see #SherlockTheme_windowActionModeOverlay - @see #SherlockTheme_windowContentOverlay - @see #SherlockTheme_windowMinWidthMajor - @see #SherlockTheme_windowMinWidthMinor - @see #SherlockTheme_windowNoTitle - @see #SherlockTheme_windowSplitActionBar - */ - public static final int[] SherlockTheme = { - 0x01010057, 0x7f010006, 0x7f010007, 0x7f010008, - 0x7f010009, 0x7f01000a, 0x7f01000b, 0x7f01000c, - 0x7f01000d, 0x7f01000e, 0x7f01000f, 0x7f010010, - 0x7f010011, 0x7f010012, 0x7f010013, 0x7f010014, - 0x7f010015, 0x7f010016, 0x7f010017, 0x7f010018, - 0x7f010019, 0x7f01001a, 0x7f01001b, 0x7f01001c, - 0x7f01001d, 0x7f01001e, 0x7f01001f, 0x7f010020, - 0x7f010021, 0x7f010022, 0x7f010023, 0x7f010024, - 0x7f010025, 0x7f010026, 0x7f010027, 0x7f010028, - 0x7f010029, 0x7f01002a, 0x7f01002b, 0x7f01002c, - 0x7f01002d, 0x7f01002e, 0x7f01002f, 0x7f010030, - 0x7f010031, 0x7f010032, 0x7f010033, 0x7f010034, - 0x7f010035, 0x7f010036, 0x7f010037, 0x7f010038, - 0x7f010039 - }; - /** -

- @attr description - Specified if we are forcing an action item overflow menu. - - -

Must be a boolean value, either "true" or "false". -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. -

This is a private symbol. - @attr name android:absForceOverflow - */ - public static final int SherlockTheme_absForceOverflow = 52; - /** -

- @attr description - Custom divider drawable to use for elements in the action bar. - - -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

This is a private symbol. - @attr name android:actionBarDivider - */ - public static final int SherlockTheme_actionBarDivider = 9; - /** -

- @attr description - Custom item state list drawable background for action bar items. - - -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

This is a private symbol. - @attr name android:actionBarItemBackground - */ - public static final int SherlockTheme_actionBarItemBackground = 10; - /** -

- @attr description - Size of the Action Bar, including the contextual - bar used to present Action Modes. - - -

May be a dimension value, which is a floating point number appended with a unit such as "14.5sp". -Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size), -in (inches), mm (millimeters). -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. -

May be one of the following constant values.

- ---- - -
ConstantValueDescription
wrap_content0
-

This is a private symbol. - @attr name android:actionBarSize - */ - public static final int SherlockTheme_actionBarSize = 8; - /** -

- @attr description - Reference to a style for the split Action Bar. This style - controls the split component that holds the menu/action - buttons. actionBarStyle is still used for the primary - bar. - - -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

This is a private symbol. - @attr name android:actionBarSplitStyle - */ - public static final int SherlockTheme_actionBarSplitStyle = 6; - /** -

- @attr description - Reference to a style for the Action Bar - - -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

This is a private symbol. - @attr name android:actionBarStyle - */ - public static final int SherlockTheme_actionBarStyle = 5; - /** -

This symbol is the offset where the {@link com.actionbarsherlock.R.attr#actionBarTabBarStyle} - attribute's value can be found in the {@link #SherlockTheme} array. - - -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - @attr name android:actionBarTabBarStyle - */ - public static final int SherlockTheme_actionBarTabBarStyle = 2; - /** -

- @attr description - Default style for tabs within an action bar - - -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

This is a private symbol. - @attr name android:actionBarTabStyle - */ - public static final int SherlockTheme_actionBarTabStyle = 1; - /** -

This symbol is the offset where the {@link com.actionbarsherlock.R.attr#actionBarTabTextStyle} - attribute's value can be found in the {@link #SherlockTheme} array. - - -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - @attr name android:actionBarTabTextStyle - */ - public static final int SherlockTheme_actionBarTabTextStyle = 3; - /** -

- @attr description - Reference to a theme that should be used to inflate widgets - and layouts destined for the action bar. Most of the time - this will be a reference to the current theme, but when - the action bar has a significantly different contrast - profile than the rest of the activity the difference - can become important. If this is set to @null the current - theme will be used. - - -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

This is a private symbol. - @attr name android:actionBarWidgetTheme - */ - public static final int SherlockTheme_actionBarWidgetTheme = 7; - /** -

This symbol is the offset where the {@link com.actionbarsherlock.R.attr#actionButtonStyle} - attribute's value can be found in the {@link #SherlockTheme} array. - - -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - @attr name android:actionButtonStyle - */ - public static final int SherlockTheme_actionButtonStyle = 38; - /** -

This symbol is the offset where the {@link com.actionbarsherlock.R.attr#actionDropDownStyle} - attribute's value can be found in the {@link #SherlockTheme} array. - - -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - @attr name android:actionDropDownStyle - */ - public static final int SherlockTheme_actionDropDownStyle = 37; - /** -

- @attr description - TextAppearance style that will be applied to text that - appears within action menu items. - - -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

This is a private symbol. - @attr name android:actionMenuTextAppearance - */ - public static final int SherlockTheme_actionMenuTextAppearance = 11; - /** -

- @attr description - Color for text that appears within action menu items. - - -

May be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

May be a color value, in the form of "#rgb", "#argb", -"#rrggbb", or "#aarrggbb". -

This is a private symbol. - @attr name android:actionMenuTextColor - */ - public static final int SherlockTheme_actionMenuTextColor = 12; - /** -

- @attr description - Background drawable to use for action mode UI - - -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

This is a private symbol. - @attr name android:actionModeBackground - */ - public static final int SherlockTheme_actionModeBackground = 15; - /** -

This symbol is the offset where the {@link com.actionbarsherlock.R.attr#actionModeCloseButtonStyle} - attribute's value can be found in the {@link #SherlockTheme} array. - - -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - @attr name android:actionModeCloseButtonStyle - */ - public static final int SherlockTheme_actionModeCloseButtonStyle = 14; - /** -

- @attr description - Drawable to use for the close action mode button - - -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

This is a private symbol. - @attr name android:actionModeCloseDrawable - */ - public static final int SherlockTheme_actionModeCloseDrawable = 17; - /** -

- @attr description - PopupWindow style to use for action modes when showing as a window overlay. - - -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

This is a private symbol. - @attr name android:actionModePopupWindowStyle - */ - public static final int SherlockTheme_actionModePopupWindowStyle = 19; - /** -

- @attr description - Drawable to use for the Share action button in WebView selection action modes - - -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

This is a private symbol. - @attr name android:actionModeShareDrawable - */ - public static final int SherlockTheme_actionModeShareDrawable = 18; - /** -

- @attr description - Background drawable to use for action mode UI in the lower split bar - - -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

This is a private symbol. - @attr name android:actionModeSplitBackground - */ - public static final int SherlockTheme_actionModeSplitBackground = 16; - /** -

This symbol is the offset where the {@link com.actionbarsherlock.R.attr#actionModeStyle} - attribute's value can be found in the {@link #SherlockTheme} array. - - -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - @attr name android:actionModeStyle - */ - public static final int SherlockTheme_actionModeStyle = 13; - /** -

This symbol is the offset where the {@link com.actionbarsherlock.R.attr#actionOverflowButtonStyle} - attribute's value can be found in the {@link #SherlockTheme} array. - - -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - @attr name android:actionOverflowButtonStyle - */ - public static final int SherlockTheme_actionOverflowButtonStyle = 4; - /** -

This symbol is the offset where the {@link com.actionbarsherlock.R.attr#actionSpinnerItemStyle} - attribute's value can be found in the {@link #SherlockTheme} array. - - -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - @attr name android:actionSpinnerItemStyle - */ - public static final int SherlockTheme_actionSpinnerItemStyle = 43; - /** -

- @attr description - Drawable used as a background for activated items. - - -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

This is a private symbol. - @attr name android:activatedBackgroundIndicator - */ - public static final int SherlockTheme_activatedBackgroundIndicator = 51; - /** -

- @attr description - Default ActivityChooserView style. - - -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

This is a private symbol. - @attr name android:activityChooserViewStyle - */ - public static final int SherlockTheme_activityChooserViewStyle = 50; - /** -

This symbol is the offset where the {@link com.actionbarsherlock.R.attr#android_windowIsFloating} - attribute's value can be found in the {@link #SherlockTheme} array. - @attr name android:android_windowIsFloating - */ - public static final int SherlockTheme_android_windowIsFloating = 0; - /** -

- @attr description - Small Button style. - - -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

This is a private symbol. - @attr name android:buttonStyleSmall - */ - public static final int SherlockTheme_buttonStyleSmall = 20; - /** -

- @attr description - Drawable to use for generic vertical dividers. - - -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

This is a private symbol. - @attr name android:dividerVertical - */ - public static final int SherlockTheme_dividerVertical = 36; - /** -

This symbol is the offset where the {@link com.actionbarsherlock.R.attr#dropDownListViewStyle} - attribute's value can be found in the {@link #SherlockTheme} array. - - -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - @attr name android:dropDownListViewStyle - */ - public static final int SherlockTheme_dropDownListViewStyle = 40; - /** -

This symbol is the offset where the {@link com.actionbarsherlock.R.attr#dropdownListPreferredItemHeight} - attribute's value can be found in the {@link #SherlockTheme} array. - - -

Must be a dimension value, which is a floating point number appended with a unit such as "14.5sp". -Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size), -in (inches), mm (millimeters). -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. - @attr name android:dropdownListPreferredItemHeight - */ - public static final int SherlockTheme_dropdownListPreferredItemHeight = 42; - /** -

This symbol is the offset where the {@link com.actionbarsherlock.R.attr#homeAsUpIndicator} - attribute's value can be found in the {@link #SherlockTheme} array. - - -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - @attr name android:homeAsUpIndicator - */ - public static final int SherlockTheme_homeAsUpIndicator = 39; - /** -

This symbol is the offset where the {@link com.actionbarsherlock.R.attr#listPopupWindowStyle} - attribute's value can be found in the {@link #SherlockTheme} array. - - -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - @attr name android:listPopupWindowStyle - */ - public static final int SherlockTheme_listPopupWindowStyle = 49; - /** -

- @attr description - A smaller, sleeker list item height. - - -

Must be a dimension value, which is a floating point number appended with a unit such as "14.5sp". -Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size), -in (inches), mm (millimeters). -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. -

This is a private symbol. - @attr name android:listPreferredItemHeightSmall - */ - public static final int SherlockTheme_listPreferredItemHeightSmall = 30; - /** -

- @attr description - The preferred padding along the left edge of list items. - - -

Must be a dimension value, which is a floating point number appended with a unit such as "14.5sp". -Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size), -in (inches), mm (millimeters). -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. -

This is a private symbol. - @attr name android:listPreferredItemPaddingLeft - */ - public static final int SherlockTheme_listPreferredItemPaddingLeft = 31; - /** -

- @attr description - The preferred padding along the right edge of list items. - - -

Must be a dimension value, which is a floating point number appended with a unit such as "14.5sp". -Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size), -in (inches), mm (millimeters). -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. -

This is a private symbol. - @attr name android:listPreferredItemPaddingRight - */ - public static final int SherlockTheme_listPreferredItemPaddingRight = 32; - /** -

This symbol is the offset where the {@link com.actionbarsherlock.R.attr#popupMenuStyle} - attribute's value can be found in the {@link #SherlockTheme} array. - - -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - @attr name android:popupMenuStyle - */ - public static final int SherlockTheme_popupMenuStyle = 41; - /** -

This symbol is the offset where the {@link com.actionbarsherlock.R.attr#spinnerDropDownItemStyle} - attribute's value can be found in the {@link #SherlockTheme} array. - - -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - @attr name android:spinnerDropDownItemStyle - */ - public static final int SherlockTheme_spinnerDropDownItemStyle = 29; - /** -

This symbol is the offset where the {@link com.actionbarsherlock.R.attr#spinnerItemStyle} - attribute's value can be found in the {@link #SherlockTheme} array. - - -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". - @attr name android:spinnerItemStyle - */ - public static final int SherlockTheme_spinnerItemStyle = 28; - /** -

- @attr description - Text color, typeface, size, and style for the text inside of a popup menu. - - -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

This is a private symbol. - @attr name android:textAppearanceLargePopupMenu - */ - public static final int SherlockTheme_textAppearanceLargePopupMenu = 22; - /** -

- @attr description - The preferred TextAppearance for the primary text of small list items. - - -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

This is a private symbol. - @attr name android:textAppearanceListItemSmall - */ - public static final int SherlockTheme_textAppearanceListItemSmall = 33; - /** -

- @attr description - Text color, typeface, size, and style for "small" text. Defaults to secondary text color. - - -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

This is a private symbol. - @attr name android:textAppearanceSmall - */ - public static final int SherlockTheme_textAppearanceSmall = 24; - /** -

- @attr description - Text color, typeface, size, and style for small text inside of a popup menu. - - -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

This is a private symbol. - @attr name android:textAppearanceSmallPopupMenu - */ - public static final int SherlockTheme_textAppearanceSmallPopupMenu = 23; - /** -

This symbol is the offset where the {@link com.actionbarsherlock.R.attr#textColorPrimary} - attribute's value can be found in the {@link #SherlockTheme} array. - - -

Must be a color value, in the form of "#rgb", "#argb", -"#rrggbb", or "#aarrggbb". -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. - @attr name android:textColorPrimary - */ - public static final int SherlockTheme_textColorPrimary = 25; - /** -

This symbol is the offset where the {@link com.actionbarsherlock.R.attr#textColorPrimaryDisableOnly} - attribute's value can be found in the {@link #SherlockTheme} array. - - -

Must be a color value, in the form of "#rgb", "#argb", -"#rrggbb", or "#aarrggbb". -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. - @attr name android:textColorPrimaryDisableOnly - */ - public static final int SherlockTheme_textColorPrimaryDisableOnly = 26; - /** -

This symbol is the offset where the {@link com.actionbarsherlock.R.attr#textColorPrimaryInverse} - attribute's value can be found in the {@link #SherlockTheme} array. - - -

Must be a color value, in the form of "#rgb", "#argb", -"#rrggbb", or "#aarrggbb". -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. - @attr name android:textColorPrimaryInverse - */ - public static final int SherlockTheme_textColorPrimaryInverse = 27; - /** -

This symbol is the offset where the {@link com.actionbarsherlock.R.attr#windowActionBar} - attribute's value can be found in the {@link #SherlockTheme} array. - - -

Must be a boolean value, either "true" or "false". -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. - @attr name android:windowActionBar - */ - public static final int SherlockTheme_windowActionBar = 45; - /** -

This symbol is the offset where the {@link com.actionbarsherlock.R.attr#windowActionBarOverlay} - attribute's value can be found in the {@link #SherlockTheme} array. - - -

Must be a boolean value, either "true" or "false". -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. - @attr name android:windowActionBarOverlay - */ - public static final int SherlockTheme_windowActionBarOverlay = 46; - /** -

This symbol is the offset where the {@link com.actionbarsherlock.R.attr#windowActionModeOverlay} - attribute's value can be found in the {@link #SherlockTheme} array. - - -

Must be a boolean value, either "true" or "false". -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. - @attr name android:windowActionModeOverlay - */ - public static final int SherlockTheme_windowActionModeOverlay = 47; - /** -

- @attr description - This Drawable is overlaid over the foreground of the Window's content area, usually - to place a shadow below the title. - - -

Must be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

This is a private symbol. - @attr name android:windowContentOverlay - */ - public static final int SherlockTheme_windowContentOverlay = 21; - /** -

This symbol is the offset where the {@link com.actionbarsherlock.R.attr#windowMinWidthMajor} - attribute's value can be found in the {@link #SherlockTheme} array. - - -

Must be a dimension value, which is a floating point number appended with a unit such as "14.5sp". -Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size), -in (inches), mm (millimeters). -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. - @attr name android:windowMinWidthMajor - */ - public static final int SherlockTheme_windowMinWidthMajor = 34; - /** -

This symbol is the offset where the {@link com.actionbarsherlock.R.attr#windowMinWidthMinor} - attribute's value can be found in the {@link #SherlockTheme} array. - - -

Must be a dimension value, which is a floating point number appended with a unit such as "14.5sp". -Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size), -in (inches), mm (millimeters). -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. - @attr name android:windowMinWidthMinor - */ - public static final int SherlockTheme_windowMinWidthMinor = 35; - /** -

This symbol is the offset where the {@link com.actionbarsherlock.R.attr#windowNoTitle} - attribute's value can be found in the {@link #SherlockTheme} array. - - -

Must be a boolean value, either "true" or "false". -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. - @attr name android:windowNoTitle - */ - public static final int SherlockTheme_windowNoTitle = 44; - /** -

This symbol is the offset where the {@link com.actionbarsherlock.R.attr#windowSplitActionBar} - attribute's value can be found in the {@link #SherlockTheme} array. - - -

Must be a boolean value, either "true" or "false". -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. - @attr name android:windowSplitActionBar - */ - public static final int SherlockTheme_windowSplitActionBar = 48; - }; -} diff --git a/android-libraries/ActionBarSherlock/libs/android-support-v4.jar b/android-libraries/ActionBarSherlock/libs/android-support-v4.jar deleted file mode 100644 index 1fbeba0932023ad6f4b851f533261eee0cb66798..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 271788 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

2{d8Do1ByJQa(4NyF4LRmP+Y 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

O0gkx4}gZP6o&Ac5xTsN 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 AhyVZp diff --git a/android-libraries/ActionBarSherlock/proguard-project.txt b/android-libraries/ActionBarSherlock/proguard-project.txt deleted file mode 100644 index f2fe1559a..000000000 --- a/android-libraries/ActionBarSherlock/proguard-project.txt +++ /dev/null @@ -1,20 +0,0 @@ -# To enable ProGuard in your project, edit project.properties -# to define the proguard.config property as described in that file. -# -# Add project specific ProGuard rules here. -# By default, the flags in this file are appended to flags specified -# in ${sdk.dir}/tools/proguard/proguard-android.txt -# You can edit the include path and order by changing the ProGuard -# include property in project.properties. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# Add any project specific keep options here: - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} diff --git a/android-libraries/ActionBarSherlock/project.properties b/android-libraries/ActionBarSherlock/project.properties deleted file mode 100644 index f28bc833e..000000000 --- a/android-libraries/ActionBarSherlock/project.properties +++ /dev/null @@ -1,12 +0,0 @@ -# This file is automatically generated by Android Tools. -# Do not modify this file -- YOUR CHANGES WILL BE ERASED! -# -# This file must be checked in Version Control Systems. -# -# To customize properties used by the Ant build system use, -# "ant.properties", and override values to adapt the script to your -# project structure. - -android.library=true -# Project target. -target=android-15 diff --git a/android-libraries/ActionBarSherlock/res/color/abs__primary_text_disable_only_holo_dark.xml b/android-libraries/ActionBarSherlock/res/color/abs__primary_text_disable_only_holo_dark.xml deleted file mode 100644 index ea7459aaf..000000000 --- a/android-libraries/ActionBarSherlock/res/color/abs__primary_text_disable_only_holo_dark.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - diff --git a/android-libraries/ActionBarSherlock/res/color/abs__primary_text_disable_only_holo_light.xml b/android-libraries/ActionBarSherlock/res/color/abs__primary_text_disable_only_holo_light.xml deleted file mode 100644 index 0edb33b4b..000000000 --- a/android-libraries/ActionBarSherlock/res/color/abs__primary_text_disable_only_holo_light.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - diff --git a/android-libraries/ActionBarSherlock/res/color/abs__primary_text_holo_dark.xml b/android-libraries/ActionBarSherlock/res/color/abs__primary_text_holo_dark.xml deleted file mode 100644 index 2bcfd0b63..000000000 --- a/android-libraries/ActionBarSherlock/res/color/abs__primary_text_holo_dark.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - diff --git a/android-libraries/ActionBarSherlock/res/color/abs__primary_text_holo_light.xml b/android-libraries/ActionBarSherlock/res/color/abs__primary_text_holo_light.xml deleted file mode 100644 index 198384fed..000000000 --- a/android-libraries/ActionBarSherlock/res/color/abs__primary_text_holo_light.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - diff --git a/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ab_bottom_solid_dark_holo.9.png b/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ab_bottom_solid_dark_holo.9.png deleted file mode 100644 index 769463b369a5185ba2d2fdf26abf058086ebcd08..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 144 zcmeAS@N?(olHy`uVBq!ia0vp^Y9P$P1|(P5zFY^S!aZFaLn02py|Iz^fCC51!MDwC ze!c%VXGhEQ)_dJsezHtpNMD|7Dac@a*_ZJyulFV2w{5C|YCbaz5)ZX-3ak0tIJ#lm tp_aeGY*)k&iW*FhzahTiJD1r}=BlLiI{(TJ=>e@^@O1TaS?83{1OUpzopr0A6)2vH$=8 diff --git a/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ab_bottom_solid_light_holo.9.png b/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ab_bottom_solid_light_holo.9.png deleted file mode 100644 index 73050476e77aa798919b829a5566973e231f9d49..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 144 zcmeAS@N?(olHy`uVBq!ia0vp^Y9P$P1|(P5zFY^S!aZFaLn02py|Iz^fCC51!MFRR zxpqaJ>-4UOe6iPKwm$=BLD{Wo!i)yScSSDT-Jo*!N?wFe;-MB!VKtu_20%tEPqwzt q4f{lgTEQ5`;-9UxjMeKCf^DQ_uhd?;-Btm#g2B_(&t;ucLK6V6dokDm diff --git a/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ab_bottom_transparent_dark_holo.9.png b/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ab_bottom_transparent_dark_holo.9.png deleted file mode 100644 index 712a551ece87b2544433ac982382a087e7f1731d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 135 zcmeAS@N?(olHy`uVBq!ia0vp^Y9P$P1|(P5zFY^S{5)M8Ln02py}Xf^L4oIp!}}xu zHrx6hVG;aws8xB@i!KMDZA_cCWy>wsRQS4KRST!En$HY_#6vK~{lt8cLjun}a%VT6 c)z9eScC>M27UGHi05qAw)78&qol`;+0QSr+Bme*a diff --git a/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ab_bottom_transparent_light_holo.9.png b/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ab_bottom_transparent_light_holo.9.png deleted file mode 100644 index bf3b9438b16543294498ba27e51d4e878c8ead5a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 134 zcmeAS@N?(olHy`uVBq!ia0vp^Y9P$P1|(P5zFY^Sd_7$pLn02py}Xh4fCCS+;oB*H z(}QQZt5vXQMa=PTZk@YrXXvE3+ofW5$)(cU#3WF_jrSY!c@8l>`*HAE!gKCvr?`99 W=bm|#aNiDSFoUP7pUXO@geCw#94y)Z diff --git a/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ab_share_pack_holo_dark.9.png b/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ab_share_pack_holo_dark.9.png deleted file mode 100644 index 6c1415772d03a71c0677f6e2461521bfae829ce9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2866 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 Q%K!iX07*qoM6N<$g0$>VYybcN diff --git a/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ab_share_pack_holo_light.9.png b/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ab_share_pack_holo_light.9.png deleted file mode 100644 index f4ff16be7323486b7fcd49b3e9bb07816a75b53c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2862 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 diff --git a/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ab_stacked_transparent_dark_holo.9.png b/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ab_stacked_transparent_dark_holo.9.png deleted file mode 100644 index 1e39572224b24a81ed4d73923280ba2724dbaf6e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 139 zcmeAS@N?(olHy`uVBq!ia0vp^Y9P$P1|(P5zFY^Sf;?RuLn02py|Iy(L4oIp!})_Q zZ}wlfoYKNk`|wbZR*CB+2cd0Do4#G+S+1#YsD)El&1Z%|BAjt`!_S2)TNKYc{m-!5 f_v_(jT(cfAPEEXE)c4^Y$T|j3S3j3^P6 diff --git a/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ab_stacked_transparent_light_holo.9.png b/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ab_stacked_transparent_light_holo.9.png deleted file mode 100644 index a16db853e94af78c0739d9b89b578e2a8021c856..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 133 zcmeAS@N?(olHy`uVBq!ia0vp^Y9P$P1|(P5zFY^Sd^}woLn02py|j?`fP(zopr08IHUH2?qr diff --git a/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ab_transparent_dark_holo.9.png b/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ab_transparent_dark_holo.9.png deleted file mode 100644 index 0eff695d82911a73874d871f3a7b23b71dd8ab44..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 155 zcmeAS@N?(olHy`uVBq!ia0vp^Y9P$P1|(P5zFY^Sl001;Ln02py?l}LfC5j;!{`N< zEvnsL$t-6rWU%$psDGg1|4DLDj`q~RzPqNgR|nl=*Rt6dx_ol~p-I||JQ4;82O1ce y*`SQyBHQ|!3>bf({j~je;Zla%ZD->HG+$+yO5M3zoXrBXjlt8^&t;ucLK6T4R5w)s diff --git a/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ab_transparent_light_holo.9.png b/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ab_transparent_light_holo.9.png deleted file mode 100644 index 219b170fa67aa2ef8e0b11ebff90c1629ba7e97a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 145 zcmeAS@N?(olHy`uVBq!ia0vp^Y9P$P1|(P5zFY^SB0OCjLn02py?l|AL4l*?;q8?- zrB_<6lUu~-<@8GYocm9fskyGHQx2!G9uAwU_k&&MlS%_4GaHYDLBatTBRp}nY76HL mkjg^D5fnx&0glSHJj>3%>1Jqp^q#PeS;bnL@oAJ;NJ=s*Cb_P#ZKbLh* G2~7YBfgFPX diff --git a/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__btn_cab_done_pressed_holo_dark.9.png b/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__btn_cab_done_pressed_holo_dark.9.png deleted file mode 100644 index 66adffed632f0f6267afe6dc2f518adb6a83ca4a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 110 zcmeAS@N?(olHy`uVBq!ia0vp^EI_Qo!3HFq_#{<Lb diff --git a/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__cab_background_bottom_holo_dark.9.png b/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__cab_background_bottom_holo_dark.9.png deleted file mode 100644 index 1d836f65a1fffea301e9cf36770b21b48b3b8132..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 149 zcmeAS@N?(olHy`uVBq!ia0vp^Y9P$P1|(P5zFY^SVmw_OLn02py|R(B!9jra;>r_8 z?%b*io|Yn;UGT9};ZTu}!9}%xc^%IgtXD4oJ@0X-F7B%4f|j+c$=0hv54CU#tNF|@ sNQ5wMgi8eI0r?xYZ}@0_Yf6jsMX$B_pXOhT0oudh>FVdQ&MBb@0DzD;x&QzG diff --git a/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__cab_background_bottom_holo_light.9.png b/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__cab_background_bottom_holo_light.9.png deleted file mode 100644 index 5818666d4e64b93da73bc3d6dc2764bcb500359c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 145 zcmeAS@N?(olHy`uVBq!ia0vp^Y9P$P1|(P5zFY^SB0OCjLn02py|R(>fCCT9!M7)Q zv diff --git a/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__cab_background_top_holo_dark.9.png b/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__cab_background_top_holo_dark.9.png deleted file mode 100644 index 564fb34b4308750b6922f320e9e114b080ecd538..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 147 zcmeAS@N?(olHy`uVBq!ia0vp^Y9P$P1|(P5zFY^SqC8z3Ln02py}XdO!9jra;!2L@ z<=I|~`ucZlc5hPnsi>TGwM)Is^N?0TPy5{UQpwgqqAoKG5)ZX-3ak0R7;B{1mWZ}( p*lxaUe)ue*Z}vC-G%ee~_}P|!&DqTD7lF1gc)I$ztaD0e0st(KG%NrB diff --git a/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__cab_background_top_holo_light.9.png b/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__cab_background_top_holo_light.9.png deleted file mode 100644 index ae21b760fb1ebecac3389164251b0fa14f580f5a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 147 zcmeAS@N?(olHy`uVBq!ia0vp^Y9P$P1|(P5zFY^SqC8z3Ln02py>gKAfB^?4dC zy{Qwe+I<(;Zrk3}qFy7o$Hqotreyxi(D>i`gF-*@tj&^T;Xws!Omj@dZ?l#4Y_?*} ivA^-x{8q}NM@;fbHo20HF^oW47(8A5T-G@yGywny6)bE3 diff --git a/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__dialog_full_holo_dark.9.png b/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__dialog_full_holo_dark.9.png deleted file mode 100644 index 79e56f522b2837bd9f579b28f037ad5eafaaee8e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1414 zcmV;11$p|3P)cSnqT^=WQ7*OFqW%ysfqGq3fLYCng$eebY1E zq0h)!qMt>^T{!1KLrdv5=!(bMwnfb7mMF4BgVA@!3k##^X|etG%o8VLfn)&kp1$5* zAHx|3EF9@?)w)=}!OothSF(h}LSVs2n}u~V8rR2gA&m?6GFm9LT5i!5ovh2$`aOLf zDMwpCv(UIN+s(qhT71rU;E=VYR%2(wIy9)U9BqNMU?EvKj~0!zxmxOREjkZzh+iq_n}2*GaEP(@ILD!5 zWBguqUH^M`clY;tz5a@wsI&tR0g7j89WEv$&WS`s3jmAj>+65+@9$R+4-crSDsl+t zoXD~ai^by4tE;Qe>-G9CHN@f2j4rXz#$jzQA^^+B$H$Mix3`1-5a+ZsO@p#5Q53}= z0G4QnFC7vyL_!;@%<@Jv>_k)mSUx>Hz18n=PE3d}%kYsC@*I)N0NNv^lI%s;wg9j! z%knLLgEIoQ+bysY63^&#(^_eOc(NT6QxTdoZI(#S<~ro`ne!tS(gH7T&zUX-UZRk7 zy|5!F77`FowzZg?X(M)KAw}<4SRP51e8qZ>m)V;$Z3?tS#CiaZ^hhEi?U_=yRh(%c zcGk9kwMUBGYjYt@pHyCSltyExNUHHFevMy@-l#r~QEjQ;(4?Q~r4samHh{FF{bU7StYxgeBAZQ`6E7N`VLYGS_ z;oj>aHT`D+d1$*FJhVBd!G+`uf(ywR1Q(Js2reXN5G)~C&xiARXWFDHmGF81Z6U>K z;#g%)oXa8RP+ENtZO$MZBP0)Pm&4Jv?h_KbHF>VdnKo?a-t;CVB(9^gh389`0#_~3 z>r7%ovdX{d8amFjk%uF>Vp~*9sp-GKg_vAO(?{&AZLdjA|Mdo3?oA8H>)1>mc|==# zB~EQxV&cD40$n%8&w#s-rjOWJ+ddiIQXYxR!^y#)tE&3)24CJ80l~J_MCXPu>Ml3AI+9BHcJ4%0r(Kw z@2dYHj4#nGKH!fqjRVUuh**Aw_CvMrs{b>Lm!YwzO4di>6N@*}Phg5Tw&B1fy2S@v zNaMh=r`Sx3>1SxA8q+hl==5I;NtblfC(XkF^KkH7ZKuDGcq0~@mC!ryi=K7WXgde? zOwz>rq{P&!A!(hIr~D!&pe-W#G7`?LQYh|`P7hzs(O!weT#2|xih3m$l64(P7wFd8 z$(YnkvI-Blh{l8EAha{kf+|%%mTX6hk;YCcRo{6`6g>|oKBz>Tb24JLyVyI4p!izS z!8wv9b%$RIiIZ@y?B&nGjRPyvaF~-xlb-U|=!P~^8?n&FNw@wIvQA!p;xDy1AK0dR zu~CaAl^btMM>A?9->NQ&|AnVmzdt!!WF>xutSl`;$84s2a_=ari#ecl- zo|KSyJXTD=1$2JI1Ql!6el7Y8-dCZ-i%gs^mMBu<;eLzP8a;YIXA&Hxi>7JtAFa#2 UvCQ(L;{X5v07*qoM6N<$g1g$KMgRZ+ diff --git a/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__dialog_full_holo_light.9.png b/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__dialog_full_holo_light.9.png deleted file mode 100644 index e029f210b9a81ed4765d31e90b6e49dc8aa37bed..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1537 zcmV+c2LAbpP)P*hY@RCILOyI+)4*Y%ioMH6eaT8-v42qXrI z0|4iGEk=d4Xm52^#H?WUz%bBygG}I|;L!cJM*+u%I9T*&&%x@0sx#0Qk0mTmeRX1h$MIxNMY&% zsz{Hz01C^N@8p~dFgXbIRub%{CUOKKzAQ3rfl0r3M&j^DZL~BnC0R+zNTfH*0>l>% z6xe!^4oO*vg0sbY%(i4Znw@-;nUbs&1zN~PIe02zy)Qcz&8uA?+OU=`?e2Zs5}uJN0M*6C#a{)YX?>^k&iO8v%U{pV&i+9YXUL@sAe1fQs10%V6ikBo z^7Qod_s{$xhgN}Tci-i5`3pX{;N4;1Au(Bm7x@)z#1I9LmdL~RrF4uC5rsHs>tE+w zbjvJ)LKv+{MYbuBrU=TBLj=6Xm=@t7;baF+QjNr0K02$09MPPz_Q^dZ5CLh8#Oov4 z0!TsP8|Jz<^->fRi@r;w5OrSCkw6L?N(J|#V;?nA78HxV{Q97DD=gWeOHxKs4U)p3 zSoD>;waz;geHn?ahed6Tq%7rduPgn zV$nDE$&ajtWS5-`4=n>hvFJNE&bxxNGnt2!k)T-g9UO0!_0BFb6cm%bLuC>qYeBK* zyN@VHxuTkNE#cFa@PaJz!! z*)p0eo;YjAyoc}Lcn`@)ql2XA#Le!l%y)3C`#|D`qk*LC#Leoh&{v9irz@IDt(4j|E-ey3YJCdAoj z17Q35`nvale)TKB+I=4%AAxk%w!OMGAf++t+Mb@Cemp-vW4j&J%V|A%#TR&cd&9%S z1Mctdf1tZ-6W>Id5JKwGXhvG!+}wOSKR^Gos;Zyq!S}5X*>+05G4|7V9G{hQ?!VjH z+iw8YkTX)YMrymYx~{`?w$U_yh$q-O1#m*zu<(hQDx}lJ70s)V5Io{ZN7v2rMwVC7 zhTm_2@1*&pTK&uP8_~o&lye*5+om^+1{h zqafFH?O0X{OUO1M^YAPb=F`bd6<0LB=s!LE=ilN39Gach?DYt$CL6UhXTc;$2zpT2dqqQrIZWT*_yH->_|IcgE|Y&S_AJ4lX{3 zlIkT6RWeyS^JtZ1q^3@yK=Cm?J&*-y*C;dpYgTSF&bztX%>V7a(kL+ra#JUT-|=or zs-McUNbE?uO3e#!@v#wf-Fu%ryG^`~69lNs`%MmnTRbrM$471B$+eE{K4hK$mCQ9h-Z$E`tJc<=E)8`p?U8s&`700000NkvXXu0mjfb2aWW diff --git a/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ic_ab_back_holo_dark.png b/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ic_ab_back_holo_dark.png deleted file mode 100644 index 897a1c11a06923f0ee630a3ec44b40118c1fa4d3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 602 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_*1rX+877l!}s{b%+Ad7K3vkswhI zFm^kcZ3hx8D{xE)(qO#|6+TOsF)%PDdAc};Se)*?;+-wxD8l++z18QgepiI9o*=R4AA9|r|3}>uTm;M6YILUxmVi!uBjgaN)~;(wEWpmNk!cW z(d%Z<{E>P~YK!lT=8FgRsYuTJwQ$0$u+I~@?rdLb^6_f+5jpHV#tRQqPS1ijb30F2_W#pYUFO#_XV=?h zOHP?#2^DqDa diff --git a/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ic_ab_back_holo_light.png b/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ic_ab_back_holo_light.png deleted file mode 100644 index 0c89f71407e8d51f92ff6a10b1ae40ec902aa04e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 546 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_*1rX+877l!}s{b%+Ad7K3vkswhI zFm^kcZ3hx8D{xE)(qO#|6+TOsF)%P{dAc};Se%}E<)W9gqsXz3_j5LNPFu1pO1DK} z+N#=yeg8w_ofMzAMJao1SUGXl-8U7Joy@GYEX@zknfd?wSxaLcYqyHhr&soQ-EO{p zw!~UfNcQJK)l+|B(yvWaZRmKvsC8=g<+E=!6%t;!XnxPxBUZuOVKlwt*0FipR-Y02 zmCh$xWIQ?dubRMH%k4r1TjlOEFztJ(`Lu4f+1J+&0<|T}CPeP?x_?Pcpm5>hNwa5M zzkQR1sjpY$)<2WmGuJ)*zvffcmaNUK`~10Vr~dw8eVc_z%*|+OqxE^sCGQ0OTrOO6 z<>J@Zf0Ym33CMeTp!xW+<7NU=B(%1ExnpuV-^$?oQTEn-hjMN&=46?A$U{|X$JUzr zjr;q)=$3Bvc`c`@@Ze;4?7{TSRWGgUnXHd<-`o)9JVUa&78r!8C9V-ADTyViR>?)F zK#IZ0z|c_Fz+BhBFvQT<%Fw{d$P~!6GB7Z{-*6d4LvDUbW?Cg~4NgrK`9KYlARB`7 r(@M${i&7aJQ}UBi6+Ckj(^G>|6H_V+Po~-c6)||a`njxgN@xNAF&x-_ diff --git a/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ic_cab_done_holo_dark.png b/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ic_cab_done_holo_dark.png deleted file mode 100644 index d8662e3f0fdae62cdee68c184a30fa9e421dc338..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 713 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA0wn)(8}a}trX+877l!}s{b%+Ad7K3vk;OpT z1B~5HX4`=T%L*LRfizez!?|}o;S3Cn7d>4ZLn02pop#z!+EApeUwz>goe2TrwSq2J zirU3kvaXhOUTIG}?do{Paly7dd_m%&JI?q_-onB2%KO8{j^-Q>wzNlYp6R5&dH;Rm z|KbvtPbZZ7*R_9QUBqkhp({MdL+G`PeiKVkcC&4Y!{nAd6Z!S-oqj3U!mzMkIqyf? zf)_G(nEp@p{`aZ-I!9g5h7aq1927O&FPT&GvG@NuQA5$TGve!iOqW^IxiY{>!{pzO z!{3V<)Sk6$zkBfg;!caFvF0E2Z#WAV9{aHQL)vPusEmizHw=GVH2J}B^#kKc_ZNxM zzDF#RGe0;TaIo&I-m~b0*sP8To$2@Yde+QKc8kg_`XHU5q@;HFk@ug+O{X5aZ~nk~ zjknIKwfM~0Z^b864VUMM@zwGAdYt)v<(Nz4IlImB@8#qJ%zn(A@Z29bd}4MpKn$sTM506307QmPCTFYr(@#O zpZ-(V%YE!?30QE(DXivDMdI0PFM+AKOT1>hnX-6tX;O6(d#2d)iSBZ_kN7m7WzTRr zzEA`h)2bz|5hW>!C8<`)MX5lF!N|bSP}jgh*T6i)(9Fuf$jaCl$hI;t2>JhQGm3`X z{FKbJN)!#IR;K1a1kqq?mJtlpAPKS|I6tkVJh3R1!7(L2DOJHUH!(dmC^a#qvhZZ8 Q4Nwt-r>mdKI;Vst0K3d3fB*mh diff --git a/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ic_cab_done_holo_light.png b/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ic_cab_done_holo_light.png deleted file mode 100644 index ed03f620f8ef9e969d0471ab76329038e25c9f0d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 737 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA0wn)(8}a}trX+877l!}s{b%+Ad7K3vk;OpT z1B~5HX4`=T%L*LRfizez!?|}o;S3CnFFjoxLn02py%z6(IY8q0$M=`{k_{&Q=;t<2 zt8!*r>&D`|W2$+>pS=eAb}M##+^cbdA4dCLPr0$oL~Mm8Bn#4$+9@L$(#*Pp%fW0&@t4F~+Q4$6OeIrG`|nG22@uVa-C zJ=H0n)NABBE9V2ZrDh$}Ob?>#U7^{{%b z^;_|*S@)*|RLscvyw85$_Y2}8p?L-UY)vO;|NFUQJ(sNEA?BESpVrme#d7mboB7l} z-Tl+e|M{(6F|!lpnSU$jtXi?CXvKcs<;$n_y<4FKOaZDTt`Q|Ei6yC4$wjF^iowXh z&`{UFLf61N#L&#jz{twj7|6CVFbMhoZ8M67-29Zxv`Q2WrdForKm^fXYnBlV)F276 tAviy+q&%@GmBBG3KPgqgGdD3kH7GSPrLyp3str&PgQu&X%Q~loCIB{EJ2wCT diff --git a/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ic_menu_moreoverflow_normal_holo_dark.png b/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ic_menu_moreoverflow_normal_holo_dark.png deleted file mode 100644 index 2abc45809c62513224e9d695542cb8dd8e8087b9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 144 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1|-9oezt=sPZ!6KjC*gdALL|E;9+*q=6m<7 zlueVX_4IZHnJ0qE#_rG0T(kiyWMEjjhCTn?qu5pu`=4q}27?c$C=-xvpo(CHaDZeV Zn6Yoz!5==w*?y}vd$@?2>|OKBsl;8 diff --git a/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ic_menu_moreoverflow_normal_holo_light.png b/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ic_menu_moreoverflow_normal_holo_light.png deleted file mode 100644 index bb6aef1d069a14a7fc1cea9780c919c61679e4fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 148 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1|-9oezpUtXipc%kc@k8uWjUIP~c#3xZ62X z=G4p^oaPsfxfS0Jish)R3f(&WG9yqa14Evg(y_dGGlfCy2iXqR3?>_SEs{VyhV?DH iJ0OaDc|iOR772{!kNsXaOPT8&i0|p@=d#Wzp$Py$I4IEo diff --git a/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ic_menu_share_holo_dark.png b/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ic_menu_share_holo_dark.png deleted file mode 100644 index 6f747c8f065940a8844587c682fb3c9443ad1ca2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 467 zcmV;^0WAKBP)SO)@i{}u0qYYqHziBfu2L*;{L?D;GxhmUqDjP ziMkTn=nm+BxmDP>FsP2fGnnz3AAnfGAiD%ptMDlguG*u-2|uL;kN%Xenfoz6Wm9neQuJ_f08buH`WL4SA>8mzG9{4uwy+$BT^9a|eO3@D0j4;gS>^u3i8D002ov JPDHLkV1mHE(I@}_ diff --git a/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ic_menu_share_holo_light.png b/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__ic_menu_share_holo_light.png deleted file mode 100644 index 682b2fdec4cdcffe042a0eaba5574fcb553c6fab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 505 zcmVavhwv6%LZS|`6cHU3BI+s;(j}rxR}U>ALI;t;n}mlvh$!J-yZtua#I%j$ zOwQ&T8Q}wUMSkBn``+6%%Cao-nJ5SZfglhBcnTy*QWjP42;RUuXn|w-Gn@r3!4%9C z+;SJ#1s`+53r;u-JS+&G)8Q=eVjwW)EYS5?U=Q?t+(O%+X%L*ae6USp(Wf44I z{VTBf*DdH$;99e18zd%PPify*mOc4h3DgW)zaXzPJFd#ED}jzd@IKXer+vefz{o(L zSH{%(p8{RZ0^V<-*kS}|(%8UCAfi$^)3kopWmIldEo%J}dR~)`A1WGIol7IL;ao9F zT=*mq(WtgX@b^ z8v#5LPB(Y&Y|7|Y_!S62?p zbb>IW`N`93fr2)kE{-7*QBRJJkl{&7FVVepxUS$Rt1LT2VAvn7lLLt0oo!v4%( tpjG6n=4tr&fORvYRP%q%M>EqU82;Q9of*be(FHVz!PC{xWt~$(699PnDoy|Z diff --git a/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__list_divider_holo_dark.9.png b/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__list_divider_holo_dark.9.png deleted file mode 100644 index 986ab0b9746301f2dd9401829da09e00995621b3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 78 zcmeAS@N?(olHy`uVBq!ia0vp^%plCc1|-8Yw(bW~qMj~}Asp9}6B-)+^BAxRtXRm= az`@Yw&#rLZUbzUUfWgz%&t;ucLK6T(%Mo}0 diff --git a/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__list_divider_holo_light.9.png b/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__list_divider_holo_light.9.png deleted file mode 100644 index 0279e17a123f8cbb3c7e3a9ce5c5af8e693b6977..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 76 zcmeAS@N?(olHy`uVBq!ia0vp^%plCc1|-8Yw(bW~!k#XUAsp9}6B-)+^LX%RmN2q0 Ycy4A9FVZ~13zTN?boFyt=akR{01+Y(GXMYp diff --git a/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__list_focused_holo.9.png b/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__list_focused_holo.9.png deleted file mode 100644 index 516f5c7399c853d112a31d1e17c8c7f17180f9bd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 159 zcmeAS@N?(olHy`uVBq!ia0vp^+#t-s1|(OmDOUqhEX7WqAsj$Z!;#Vf2?p zbb>IW`N`93fr5^nE{-7*QpO1)z4*}Q$iB}R!lH3 diff --git a/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__list_longpressed_holo.9.png b/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__list_longpressed_holo.9.png deleted file mode 100644 index 4ea7afa00e2bfe057472ed5a196080fc80ad7383..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 154 zcmeAS@N?(olHy`uVBq!ia0vp^+#t-s1|(OmDOUqhEX7WqAsj$Z!;#Vf2?p zbb>IW`N`93fr2)kE{-7*QBRJJkl{&7FVVepxUS$Rt1LT2VAvn7lLLt0oo!v4%( tpjG6n=4tr&fORvYRP%q%M>EqU82;Q9of*be(FHVz!PC{xWt~$(699PnDoy|Z diff --git a/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__list_pressed_holo_dark.9.png b/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__list_pressed_holo_dark.9.png deleted file mode 100644 index 5654cd69429fd0a3502a05b5f827bffab89cc7e0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 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 diff --git a/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__list_pressed_holo_light.9.png b/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__list_pressed_holo_light.9.png deleted file mode 100644 index 5654cd69429fd0a3502a05b5f827bffab89cc7e0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 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 diff --git a/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__list_selector_disabled_holo_dark.9.png b/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__list_selector_disabled_holo_dark.9.png deleted file mode 100644 index f6fd30dcdc9c39c836e509486854f9da03486892..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 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#DAm9s(?cuyC{kcif|*Eb3_81S$-+V)J@yPBVWyvqG&GeYz~KYxJdw0eeyIoHJnOEfn# R{sUUY;OXk;vd$@?2>|r{LWckV diff --git a/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__menu_dropdown_panel_holo_dark.9.png b/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__menu_dropdown_panel_holo_dark.9.png deleted file mode 100644 index 4d3d208578c61662986fdc16bd15c69759b48d6a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 922 zcmV;L17-Y)P)!ytdud6iMT7O&4bD*mP3eKws)UN7D2k#e z%DbYt@4NEYnkjlINEK7=*RV3zwml#Px9r!q%}Y$QM*NqHEZ-wscn^ zf4p9=Kg#ZZAKY%YZvc!aCbL}F6eGxtBSzy=smEUmc6C{?q1YCQrid~5o$!73+BeU$Ee{DI^Yo4#-o87 zao*xiE9Z<+s}ttlWw19HGlEA1nW09+*~|#}a;CkeJh%bU1g9CP5h0^O2}4Hs%y=Lc z5q!OY8j*^uk~rBBK?ljmh#jL84Ev;rDo>_H#K|6e%Mo=CgLzw$rI$Y4Z-kUy6U47Z zMI2w^tmuV~pH%tJq!^(yWY-hbFl2;G2g)+VPqud2Sicc+jL>MvBTKK;HbN#jlrS<8 zl+;FqdPULzJ~Kh_!?j8>!xs^*nQAm$#290~ue;BBnY1w&wMw4#m(pwEDZd_oY1{Ux z>$>N)H(eWD*FCpw`-IsDKF28-6~1bz!JGs-W6Z&R1n>#KR{&q8us99Q}8ID#(NJr3oa@N-D4Rc$qhA--bT2} z_Wpf@Z`4749}#V+fwWJz^oyZKO1~J&exY-1*Kg?D$hu!fixvAiNfpmG;mo&f5BSEA wlE;@gYed_N;JFm#Y)Zw{1W}kQU9GkF3xsHEK4Myn7XSbN07*qoM6N<$g18=|djJ3c diff --git a/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__menu_dropdown_panel_holo_light.9.png b/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__menu_dropdown_panel_holo_light.9.png deleted file mode 100644 index 924a99d173082ba58ca7527822359f228bb14dec..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1061 zcmV+=1ls$FP)#d)-&;4-At916hopygyW1WQa|lkCWZ4-q&QLYwjy>%Jd>?UvK6*fy zdt!`Ep~K-gOUxeEG;B7TCA&L&Y`5FR`f3tF5S^VH!lJsKJqkfK0&PN7nPcRS?`4Ev z7V~vPKouy~L@5%v*=&-(hy0cgM*ETwjWz&8F3NVhH7#V4$3+kVgi2lPw-adOTXm|2 z;f`P0rx+seIw-H@dwPaOx@-q(hY$i2BS4u1XM~+%LI5%mN(D;0XOsl63U@~43e6EU z5mrW96C~;L2O}H%p$jmGc5)7LM&^oyAacV=14{s_wp`K^YIpyDFEM02mXk3OSEw-p zdORS~SGTvf|Cjl{`o#71_3u-2KzcK(ZU7La5JAil5&>9olp#5yVJhG_L?OnQ2x7(v zIfg2+Q2z$cZ7gkJK~)>%8)`3CJSNBlBGKwWz;6QnLDPCN+(q9 zAJ*09wM4d_hZLYxWa z2;mvCbu@F-B1H21)loz{?U-+?@nqk8kw`Vm31QkJFg_V%{OMfZr8mlq(-<|uJGVoHpVClAlh&-bsduQ(hI zi(GsU`1tt1hf_X{d`3<68b|S{tXYwd2YXzXl8Izg4y^21 zp<@H92ON{kB3P1HizBE$;EP~xzks74y{^`3Ur7(FmPO0@t2+WXW`VN|Gc9|AJ43ds z=_5ZJGT6$YN8bIa6HYZ^jFIn`&>W#9La9l$?6@3`ET&WsUkjFK0@?|yO)(6`*1l_s~_L1z$~& z@jZM)qqe)$B+Pe}79nG2sji9uR0#8Z){~%#a(p4yPG;@1CipK8G=YCTO^$u*mj`Me f=rGa5Ym5<}3Pv>t$oVA_00000NkvXXu0mjf+qu}} diff --git a/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__progress_bg_holo_dark.9.png b/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__progress_bg_holo_dark.9.png deleted file mode 100644 index 310c368e7a68479307866c479d1e4eefcf5db311..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 178 zcmeAS@N?(olHy`uVBq!ia0vp^96&6^!3HF|1ZAax6icy_X9x!n)NrJ90QsB+9+AZi z4BVX{%xHe{^je@`h^LEVh{nXLlN`Ak3Qu?vqkba5WyT9CKZ;N%wBhP~?hKK2LK3q{Q@b8ror6q0>Kp=4vJYD@<);T3K0RYm>I5PkM diff --git a/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__progress_bg_holo_light.9.png b/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__progress_bg_holo_light.9.png deleted file mode 100644 index 70cb7fc7e0bcfb850d4b365f1bccb5b743913e21..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 174 zcmeAS@N?(olHy`uVBq!ia0vp^96&6^!3HF|1ZAax6icy_X9x!n)NrJ90QsB+9+AZi z4BVX{%xHe{^je@`fTxRNh{nXLlN`Ak40u@7AASF0zb~yy)74d)-}Q|XM+&=H%L1l~ z70X`DZ5Q8J;=>T6aJiv_zhUdQx9rw$B!4Wi^!v;8!uD-LM?h!CZ3$B@rZO?tz^Iy& QK(iSCDOJO>Ym5d24oA2hD9A9kkZ#C-ocYxQulY$%dG^s1`jD zWrBMf{hI5z?Ps6d&cAMwxpu9tAQSLC;sV+l?CI!atlqGv_K~X}S&7D6#irA$G%zcr zGa^}SvXODrvrsWB#ZkB-c}-Y}>Q0!#L#9IQCX$ZI#7DnF9fJ8(R=8iR{NJvIR3GfdBS0fGXvSYugM@B@Fy~s_l`Jy)|ccqHxmVzApHz{x4N{y z#Xj0V$LH=@zsWY)$4Z)6--edG^VYGh&b$}$F3XeLt5=Uu0`p37@FaypB&t$KuAm9R zq*|yt7WOdr(m%g{dU1bs0-qy(nh~3JDc<<|K^(;cR4G!8UrKd|p;N zi5zZftW#Kk#vM}fdS+hLQ#;Dq?H?_`8P1nhqmR=j>Au${MMR)hh&5HCA z?cjx6pHV1ZFFx`ra1m|YMALE$u3RAxZp(6Eus@DJwzn!G7Cw2Mm%K&AN5Ia`DuuPd r`dvHM#yxB2nYDo;0!e2cs)*3P7gB8$K+RT%00000NkvXXu0mjfr&_ZI diff --git a/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__progress_primary_holo_light.9.png b/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__progress_primary_holo_light.9.png deleted file mode 100644 index 1c269205e874bc6addc308efe5be4fb7c5da0edc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 917 zcmV;G18V$CDOJO>Ym5d24oA2hD9A9kkZ#C-ocYxQulY$%dG^s1`jD zWrBMf{hI5z?Ps6d&cAMwxpu9tAQSLC;sV+l?CI!atlqGv_K~X}S&7D6#irA$G%zcr zGa^}SvXODrvrsWB#ZkB-c}-Y}>Q0!#L#9IQCX$ZI#7DnF9fJ8(R=8iR{NJvIR3GfdBS0fGXvSYugM@B@Fy~s_l`Jy)|ccqHxmVzApHz{x4N{y z#Xj0V$LH=@zsWY)$4Z)6--edG^VYGh&b$}$F3XeLt5=Uu0`p37@FaypB&t$KuAm9R zq*|yt7WOdr(m%g{dU1bs0-qy(nh~3JDc<<|K^(;cR4G!8UrKd|p;N zi5zZftW#Kk#vM}fdS+hLQ#;Dq?H?_`8P1nhqmR=j>Au${MMR)hh&5HCA z?cjx6pHV1ZFFx`ra1m|YMALE$u3RAxZp(6Eus@DJwzn!G7Cw2Mm%K&AN5Ia`DuuPd r`dvHM#yxB2nYDo;0!e2cs)*3P7gB8$K+RT%00000NkvXXu0mjfr&_ZI diff --git a/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__progress_secondary_holo_dark.9.png b/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__progress_secondary_holo_dark.9.png deleted file mode 100644 index 40d0d1645cbf05e30bf092ace45403281da7f318..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 188 zcmeAS@N?(olHy`uVBq!ia0vp^96&6^!3HF|1ZAax6icy_X9x!n)NrJ90QsB+9+AZi z4BVX{%xHe{^je@`oTrOph{nXLlMZq=7znVWA2oV&$ZSjW?F|h7ziq5jS#e}ezd(V) z{M(JTeF@SBrcbxn{QE=WZYK^04VRD=846z*9&b9ovtVvpnl(eT%D#{N!SzC3^S3#* f<|u1MCr7h0-;i__`(soEw28sf)z4*}Q$iB}%FaDT diff --git a/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__progress_secondary_holo_light.9.png b/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__progress_secondary_holo_light.9.png deleted file mode 100644 index 40d0d1645cbf05e30bf092ace45403281da7f318..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 188 zcmeAS@N?(olHy`uVBq!ia0vp^96&6^!3HF|1ZAax6icy_X9x!n)NrJ90QsB+9+AZi z4BVX{%xHe{^je@`oTrOph{nXLlMZq=7znVWA2oV&$ZSjW?F|h7ziq5jS#e}ezd(V) z{M(JTeF@SBrcbxn{QE=WZYK^04VRD=846z*9&b9ovtVvpnl(eT%D#{N!SzC3^S3#* f<|u1MCr7h0-;i__`(soEw28sf)z4*}Q$iB}%FaDT diff --git a/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__spinner_48_inner_holo.png b/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__spinner_48_inner_holo.png deleted file mode 100644 index c8358e9cefce502030416e05dc8faff139b886b2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2081 zcmV++2;TRJP)YIdx5%v}IY-E={))x>B}kD^;1aO=v<01PBB|;(|LQ1lm?k zLWq;Nn-CY=ae0(~!^>I`t6s zs-B%JpquWw-vVT&b%#DKYKZiAR|9AYVtSC>+D1~E4^t2*_YE}4C7t2scS_b&i9ji7 zBYSvMwdlT0Go+O!I1;=rq$n|BisnJx=53v0;@hqm(7l)*=4rJMo!clNrP~Z@m{E-} z^JZ{ZNHx@{flX?mQSo``X|C|5u79fpM_&?X60Kt|A5rbxJ7+XZpRQ<_6xsZ!_#wo! zj#h1_U5!M-Io2>ob>UEYg+LRijsxnVI$Sub8=TigMynU~iXTIjns`*ZXjCM8l?je< z^3e1OfW}cB&*(9#LY#4(p+|S(CFYo)RH;RK=~N=zD5YZ@e|b@)#etF>)Z-yez@UzD zxn@bF&zGN~8oIPk4dfy-rEX5Ww8$EZ0F70%U;9F1W%-Z($&Ga-Maup1vncKQ7_DKl zn9!@7d$FjFqs1PKM)U|Dr6$Db)oTnV%fNxx{Okxr+DM%Qs^$R=K0p5VBBLXP|Go*uWAqrP!s#9EjG3Y5H)_%&0w$xIP8)2<gS?toB)4w_5VP~5v52jeNf?a@l%z&Ft# z7nB8|dUgD~fFBhAa+9}!Fnz66uJJUZMq$&Z-=x+YQJfJpw%hO;S zbE}u#&MHNeP>Upl#AP)>l0hdeKfNO4(#tQm-Akeu&02@RbFR7XY>6_k1%f(YAT(#fsAW zCKBlg4QBOIpq?mn>zJh1X=9x9hp4F}kQ(@481j?!sz3o)0BA?xOCB;{@vwLHR_qA* zZA`n>5_V~?==zrnj46C`9p$WNjB&zGc+-W7;QUT(*KSn_p>ds2!NyfVppL*7{NFHR zx3J%}=U0sLd(^D`)P?PxcXaJb1;-WXet3d^dmIcA@AOk%p(p(THF8j!=km|#V)bYd zpicX$PljfTc@O)})|@FD=Z~mC2i2imPj;N6y7k2(V~h2N*p=p#-z6}HxcB*hYkSJV z`IFSdb9yY-P}dA6b@>ZL?=z9&3we?^d^OD4aqs1Mx13&f#Qiy{cDn?wohTPSPjL-WpW1m}O&Ju5YPHyotYlm=9`GcY zrwYvY8;-f&ZSM33oCpsge2-Ip%afm3V!sl6q6gM{kN3J3%|Xrhwg)`uVUIiGY!FzE zIO3Qa-0aQX;)a}NjB&uQ|K;9KmvHqg(MeCoc*sw<&DEj$2|GyBp7MmJgBi=!jyvfZ z$6Ymtf^mwAKHp@Hd-~&L-Nsi~>l_hPjymE9wjDU*%(E+7 za!uA`P2O+vKSpg~;?JJlUH||9C3HntbYx+4WjbSWWnpw>05UK!F)c7SEiyAyF*Z6g zGdeOeEigAaFfi_TCsF_a03~!qSaf7zbY(hiZ)9m^c>ppnF)=MLI4v?WR53O>Gc!6e zGc7PTIxsMwC7)_* diff --git a/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__spinner_48_outer_holo.png b/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__spinner_48_outer_holo.png deleted file mode 100644 index f62f74bb38e8818fd970b7ec1f7862e543cc9d07..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1811 zcmV+u2kiKXP)Q(x@RlU0R z*6*F+o^#JDHf2*b#j2Gf_PMBSbuGRn) zDJUkGcinCw!4`)d@_D~EMJnC5dvGXBz z^GjW6Gg4BPB{MBwxqQWN<0fP#?6J=Sj@WNJ!AH@8Kl`>9L$xnJF(@mqT0WPnt1qF1 z=Fx+;deGw@bGK5OQ+L*P{Upq+6DX1yGQbK>T~%EkI?XGa@}$o>ppa%>^8?Sie*2l7 zfHK3%D>%7|N++0Avr7*8vd@}G^Jo0fcfyUHfnsLZ&jU?a6Rn7I58e-AIzUHA66jy!AvGyBgcAIA_8&ya%2-o5w@+x^Frq z7x5uqjDu?ciVPZ-34&-=b^T>U$i3owu8N|PCmm@W9a)>Z@0e@OLVt>;Q1iTBsK`Y- zJ#Dm0pva)1q@Sv}wFUZZ<(6Yki*muoJ=kjDtmVDYq#tH=k$<|@5vTpkf+%-~CzQJb zDj5=FGBxvks&SW*YJTnCqA2*7ySf013>jGQpITpe;Jn|eigLRhZQhTXHIx~a$pm$C z{nZbIsz13R7nL1tHd-@KF*$Um(og?cC1;!x<)VYeI|B_UB@HdgHw5UWlj@?}cDp+O zMal|-j9w2i9i`?Cb8^v;J)JZZ3@FG_LfsGv{MVdZZorO4w{8Y134%<%0TH$=m)%OW z_@u(SziK>nET6ihG`KOcU?%zJh~m2+ycN)r5;qQq+h%%Xy;f)Ejn0a3UnsuS^+vZqWP#0th z#x}@k!|oI0qU+rNRV>J4GUFR$v|a9z%jMoM-5IE6CMAy{ll?bZ%p5f-7cDwzt|L%b z^86*Y-fp1pM3X+OAj(~JqWJ*PYCpbZCY5MgZSAj)V(>vz$zUg(ZywPKsOqx1Or~s4 ztCPVxWShrQgx&N<^IZW2u9-7hOofKj5BzxpoW= zdO}GqH|+&2+j}j6LUh@cv}2FCzaLvtWZ?^TwHb8;v&L-C`+P^-e$fT!yBz5Da{oL7hj@h;h3%R$P7X_J;dmT2? z8&V8*_<~22M7c%3b3D}BjlNwczv7fZds1ebGU8;svesTmESU0X4=BlHYF_eOt8iaY zL0I~yq8N;M$m4dU73%)xM=srNe&@#dxWo1;CZw8+{^f0pouFbc zV#*`lZz%0)HGlQf<_c&{Ktx7;z}?CzodgvZopY&OUp7)Q;eaFVO?})iuy4L9j zyLs2K^qSz1EvYP7>Ws{|~_-QddT;IiL%she&}m+lY?b~t3u zik_CPT+O0+6?K`iA!CLOr{nnY$OW(ay)*42s|TRe$lC9I+YPJ$b-IG8H~q!myML>= zroa>ruDyrb zV`&jHgSNQCgmI$=lu=hRYuXKOo3_xM&-4jsmA;l<3@^Ph&(-?zXM#=Hludb0$^QZH zs3&Vcm*{c;001R)MObuXVRU6WV{&C-bY%cCFflPLFgPtTGgL7)Ix{mmGBYhOH##sd z?sz9s0000bbVXQnWMOn=I&E)cX=Zr$HaasiIx;gYFgH3dFrOu# z?f?J)8FWQhbW?9;ba!ELWdK2BZ(?O2No`?gWm08fWO;GPWjp`?002ovPDHLkV1l}_ BPJaLZ diff --git a/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__spinner_ab_default_holo_dark.9.png b/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__spinner_ab_default_holo_dark.9.png deleted file mode 100644 index eb28ff9a5516c15667fa8fafbc22d608d1f77a06..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 311 zcmeAS@N?(olHy`uVBq!ia0vp^%0O(y!3HF+1t+BgDVAa<&kznEsNqQI0P;BtJR*x3 z7`Qt@n9=;?>9s(?o1QL?ArY-_Z*Jr|WFXM+FkX}IYI~tj_}8!bFJ^a4j((ibs-&WN zGIsXEx)Wtn`lnsEAmpSFI79ccn9RKAsn<`<tk;t}o>yjV{qp%WbL{dki&M)*dw`x~@O1TaS?83{1OTcY Bcf0@q diff --git a/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__spinner_ab_default_holo_light.9.png b/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__spinner_ab_default_holo_light.9.png deleted file mode 100644 index d281adb553af892f758407b846bf31810b9d776b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 312 zcmeAS@N?(olHy`uVBq!ia0vp^%0O(y!3HF+1t+BgDVAa<&kznEsNqQI0P;BtJR*x3 z7`Qt@n9=;?>9s(?Tb?eCArY-_Z*Jr|WFXM+FkX}IYP%rckLbO*zpbz{y7bYSIrPClD)2Hc3qcaC*%7oYhKR%+5DyWbJ~oU4#{OKNlluqE0VJm zR?Ud&kaA;Q)O4{aB-unUR3g{I@EB82%f_aZWF5r`AFqi`v@HN~5*v&Qo>cRA$gv99 zHaapFv&*%1#4~?bwda`9)~}vNKHF@K`t|cGZ}Xb{RR4x!PC{xWt~$(69DLj BcXj{( diff --git a/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__spinner_ab_disabled_holo_dark.9.png b/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__spinner_ab_disabled_holo_dark.9.png deleted file mode 100644 index b2985860907ac324b509b76731e8ef9e01bcef39..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 306 zcmeAS@N?(olHy`uVBq!ia0vp^%0O(y!3HF+1t+BgDVAa<&kznEsNqQI0P;BtJR*x3 z7`Qt@n9=;?>9s(?E1oWnArY-_Z#r@{8;G<#%>2r*^uo7)-)HXL@_O1Ny%Iq#{YfeF z(mvLmIJH1t&`=}DOJmBWhqv04yB582t6X;JXNKdwfEg3JZl{PztUeIIdQ8h8YDr!LqoiBzejNy&kDcJs%rP689)vmGI{X_;^jtl6gm^<0^v)GdFRa+YOJx z7F>vKtz@b&Rr+MtRJ_Cdn)*bIu9V&{pI@`*?C`z(Yf|Vzp#K;=UHx3vIVCg!08ssU A5dZ)H diff --git a/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__spinner_ab_disabled_holo_light.9.png b/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__spinner_ab_disabled_holo_light.9.png deleted file mode 100644 index 4215396dd4e51fea9239323d313b72fde0ba86d6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 306 zcmeAS@N?(olHy`uVBq!ia0vp^%0O(y!3HF+1t+BgDVAa<&kznEsNqQI0P;BtJR*x3 z7`Qt@n9=;?>9s(?E1oWnArY-_Z#r@{8;G<#%>2r*^ujlV;{V25Ur(E)S0c!zKPhEi z+Q+&RrxwTy8fpZ2X-wJl@K&30*P>T$mCG*u%y7IHFk@oZ?G!PI)dwP2k7*f%?N0KT z=P~Pe`QZt37-AUDv?qm~sFi(Y>bsQr3FCw4S+92))lbOG-Y30G>`_~0 diff --git a/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__spinner_ab_focused_holo_dark.9.png b/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__spinner_ab_focused_holo_dark.9.png deleted file mode 100644 index a280eabf59b5eb69fa2a84280402b63d5e1bb8f0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 524 zcmeAS@N?(olHy`uVBq!ia0vp^%0O(y!3HF+1t+BgDVAa<&kznEsNqQI0P;BtJR*x3 z7`Qt@n9=;?>9q_DjO#pI977^n-`=$MKI|ZI{A2#4tV=npb9cQAXy4X!_bwM}{Q4K( z1sl8bnxc=22fURRmTQmkS`l-5N%{4LzmAq3{WkJ?oSyR(lyW*m>cW(jDj1r7drC_% z+Ahf4U7%?EfVHA#U$%eE)HUhV{* zGqMRv58QeS1t+_UJh{!Nwtjop`q`x&KXzE!mvvsrOU)9V|3+xFYu0w7ttSN+pN66C zV4oMA@AG&3wK%+`$wcPZ<#Ux2T-c9-*heq_yZUm|{V%D1UlxhJm0zYfUETgVr;hpA zt-Fj|Jsx=O$lYh^6WL+vBibSA6WURD#!g`Ij9SHG25Jg!2FnzxlYN}N9h%V=a_mM! z$e|leQ;yweap>IrEpmd};fhV2Zrn5uN|m^)*v*dyQIi{G2ej@g`j zy#1roz10ezmNeBYwbLI^0W9{MT&2dcxOa)`zb@?O?Gu2 z*S413TzCHUdV}>`f)DaiKP_4HkL&Y-WAl>F%y}d1AGY65et#XKh5dqWo7Y|}14bu< Mr>mdKI;Vst0N8Ej(f|Me diff --git a/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__spinner_ab_focused_holo_light.9.png b/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__spinner_ab_focused_holo_light.9.png deleted file mode 100644 index f8d619b4d47ab5b104d6b1042c27fb16a3beca47..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 523 zcmV+m0`&cfP)C3<00004b3#c}2nYxW zdK`GU$CA-E+tg1FUj3CV1Ez}l7r{NB_YWZ zgb+-Kh;2qAgunr)owSNT9jE|#(}iQ{0=K~F)j_f4%AIwfW*LI4SCjSena$3zhl@?`-N)f>fC&00iU>|7tSL}YGdG832Z z7Ry93w=$W@5~IozqskJa$`YfBUCf~8@-tLEe(Yg7ZJ&$d5^vAJVlkbz&)H#>=1rCU z=lI*@D9QucAy4<)W_$YF0~q6}sI5vC!>ie*fX@E1>5KTAKqegRE>ywO`Fw(I}^ N002ovPDHLkV1grX;W+>R diff --git a/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__spinner_ab_pressed_holo_dark.9.png b/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__spinner_ab_pressed_holo_dark.9.png deleted file mode 100644 index 955a2f34061ae8ac853050da355f89409fa0a784..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 464 zcmV;>0WbcEP)C3<00004b3#c}2nYxW zd0`Pl=$b2!s#>@tS z$Y#JV#)+K6SU+tW#+_RkXYzpRi_e9eTN!5>F{(z4su81V#Hi{OLkTB`etUYuM1<4( zFh4)_STHCiBAh-(+2ze7j|0M$*V@)G5^^0JhFHh^fzV_7Tf?-4Si|T*tYCB@#xY$W zMloF>#xN!zMlhxzoiQdMoiL^$+87%UEsQNlYm7|@05m?}iO1-}bYl(D3Ue3c7gw}A zD?zp;CtICi-;5NDtN#ybjCs$)&yQmArGt<$4!&l7(HXO5p7J23`oDJvMC3<00004b3#c}2nYxW zdPRE!~6H3V|7LaeL+kwzxO}{DvWjdA^uWhB*Ox4MVbeVt$Spwgkx< z!VkuXjKgSuY)h6Hw=%|LL;AyKLdLC(F?ASO9Y$7%k=0>jHH%rr7Kwb5&>UvDaCo}j z=j+357qeVAJX{{~a_138(!I8ROa__X7ee%7enXtUzOE0mAw(ah0z?m{B1Ao=21G5U zCPW=Z0YnW(5u`pwA*3EgF{C<11Ed;86J&FYMhHOp8-||_vny?o%`ne52fWVraQiWC zKdv-wupMF9(yd;3%<<_PN8|TOh%C!a80|#$F{54SO;q)d{~Z)(nS?QFWpYf|szS`q zFpt2hCCEz5&mZk`@i_(t4MLWruXxh=CcXUn1{k8P{&E{)e*gdg07*qoM6N<$f@(ay AcmMzZ diff --git a/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__tab_selected_focused_holo.9.png b/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__tab_selected_focused_holo.9.png deleted file mode 100644 index 673e3bf10d60cc54b6dfef2fcda24575073adf61..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 147 zcmeAS@N?(olHy`uVBq!ia0vp^tU%1i!3HFsuehcLq*#ibJVQ8upoSx*1IXtr@Q5sC zVBqcqVMgJWBc+iXw=G=Ra=)z4*}Q$iB}l;b6k diff --git a/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__tab_selected_holo.9.png b/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__tab_selected_holo.9.png deleted file mode 100644 index d57df98b501944b4ba63623766c396b5bccc29ee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 148 zcmeAS@N?(olHy`uVBq!ia0vp^tU%1i!3HFsuehcLq*#ibJVQ8upoSx*1IXtr@Q5sC zVBqcqVMg}h~fd(*my85}Sb4q9e0H>EG$N&HU diff --git a/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__tab_unselected_pressed_holo.9.png b/android-libraries/ActionBarSherlock/res/drawable-hdpi/abs__tab_unselected_pressed_holo.9.png deleted file mode 100644 index aadc6f87b21d7d5139f3bfe860f4c289f75d241f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 145 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 diff --git a/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ab_bottom_solid_dark_holo.9.png b/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ab_bottom_solid_dark_holo.9.png deleted file mode 100644 index b2293670b7fd0f1d20efadcb85df764eaf8f996c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 134 zcmeAS@N?(olHy`uVBq!ia0vp^QXtI11|(N{`J4k%zMd|QAs)xyUNz)8;K0FpacBG8 z{r_dveK(bI?AYL#c;KCB(}&!U`A=evwJLPDoBk{4*AEnmdKI;Vst0H2gA*Z=?k diff --git a/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ab_bottom_solid_light_holo.9.png b/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ab_bottom_solid_light_holo.9.png deleted file mode 100644 index 0706c8af658bde9602634950dfe3d5fa5886163f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 134 zcmeAS@N?(olHy`uVBq!ia0vp^QXtI11|(N{`J4k%zMd|QAs)xyUfsxfz<`JK;_Z5A z-Y@ApO*&r-OgQM+#9X>wkYiu(tId138dhyGKCm}H$eLN@qysZ=3D*)nlM7YC@0xyy hn}nCMmBhQI$CPR`ipOiMnG7_T!PC{xWt~$(698&aE5rZ* diff --git a/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ab_bottom_transparent_dark_holo.9.png b/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ab_bottom_transparent_dark_holo.9.png deleted file mode 100644 index d814d02d31183b8f00f475a05c124004983d9eff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 123 zcmeAS@N?(olHy`uVBq!ia0vp^QXtI11|(N{`J4k%PM$7~As)w*fBgS%&%9EC|%_%783w8jlt8^&t;ucLK6TeKPwmj diff --git a/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ab_bottom_transparent_light_holo.9.png b/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ab_bottom_transparent_light_holo.9.png deleted file mode 100644 index b139c8e49168e4404df0a46b30a4b30e90c1ccff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 123 zcmeAS@N?(olHy`uVBq!ia0vp^QXtI11|(N{`J4k%PM$7~As)w*fBgS%&%9ECY>s_{MVWOZ(=mjBT1_sGr W&p6(H%v1uJ#^CAd=d#Wzp$P!PC@9VV diff --git a/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ab_share_pack_holo_dark.9.png b/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ab_share_pack_holo_dark.9.png deleted file mode 100644 index ed4ba34ecd9f8ab8c557924fafeae6a89307bd7c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2851 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 BM!Nt2 diff --git a/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ab_share_pack_holo_light.9.png b/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ab_share_pack_holo_light.9.png deleted file mode 100644 index 8f10bd5222239e82e49c5120888fc9a07a324b42..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 122 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+1|-AI^@Rf|M^6{W5R22vKmPx>XSQNv;&5z| z@wwFK#IyY<~E UNZ9H+7ibuRr>mdKI;Vst0LZr`*8l(j diff --git a/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ab_solid_dark_holo.9.png b/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ab_solid_dark_holo.9.png deleted file mode 100644 index 743d00b6cd7e446c7badca9dd11d1579404569cc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 133 zcmeAS@N?(olHy`uVBq!ia0vp^QXtI11|(N{`J4k%KAtX)As)xyUQ!e~V8Fq8aW6aH z`M>?!MSK0VJ5DH+1)MRKpSquM-S5BdOIN+&sn~jE%jQNlsf-1UY_}X6mMgq#dKVMx ha^q%Y#@a>3az|3`-r6;1y%^A322WQ%mvv4FO#tkfF|q&v diff --git a/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ab_solid_light_holo.9.png b/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ab_solid_light_holo.9.png deleted file mode 100644 index 17c1fb921f9b7b46aaeefe7afb8302874fb0abd1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 133 zcmeAS@N?(olHy`uVBq!ia0vp^QXtI11|(N{`J4k%KAtX)As)xyURua|z<`JK;_Z5y z;?s*`91mY+Vs~LvSAIRQ|I~ek>wo_(4hk(}+Y^;`>!t%UugL`m=C=w5f(6PQ%h%~C hy?JA^CG4Uk|5eN5b2qlEYyz6g;OXk;vd$@?2>`YpFM0p~ diff --git a/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ab_solid_shadow_holo.9.png b/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ab_solid_shadow_holo.9.png deleted file mode 100644 index ddfc8e3d5c4131f2460254f183938477fc5a0679..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 168 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+1|-AI^@Rhed`}n05R21qr&#kfCPg`@kT=WR_nY-)l@u)2m z9YjR(TNrC5J8zlf@MOx-MX#^q?zd~tP;1Ok`WbQLQ#YGy{=Yfu7pEGW;JmVaai5Cr S@!LSF89ZJ6T-G@yGywoUXh2*5 diff --git a/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ab_stacked_solid_dark_holo.9.png b/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ab_stacked_solid_dark_holo.9.png deleted file mode 100644 index 007a4b239244212339b817f8de9474a4dc34fde0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 134 zcmeAS@N?(olHy`uVBq!ia0vp^QXtI11|(N{`J4k%zMd|QAs)xyURua|z<`JK;_L&H z*gyPBj&nSGnTg$nOT)YjBQU;+O3-o%)BNS9GKrK90(RDcPwA0 ir}XBH&6co>lKfV`a~Jh`>I4G~X7F_Nb6Mw<&;$VSc`p(G diff --git a/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ab_stacked_solid_light_holo.9.png b/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ab_stacked_solid_light_holo.9.png deleted file mode 100644 index ad6e1a4d9f3c81e20676f979a53cea2084ce903d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 133 zcmeAS@N?(olHy`uVBq!ia0vp^QXtI11|(N{`J4k%KAtX)As)xyUQ!e~V8Fq8aqs`F z7bNtyi1zwxcbrft3piseKXpIjy5E1@m#%ulQ?d2Tmd%Z9QW*;x*={*DELV8f^e!gW h<;Km*jJ1o5{)rFFF7K diff --git a/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ab_stacked_transparent_dark_holo.9.png b/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ab_stacked_transparent_dark_holo.9.png deleted file mode 100644 index 0ad6c888b4c7e436e7d7c78432dbfdaecc95a7ac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 127 zcmeAS@N?(olHy`uVBq!ia0vp^QXtI11|(N{`J4k%Zk{fVAs)w*fBgS%&%9ECxB?U?=uVx Y$^4u51wHGE0Gi0)>FVdQ&MBb@0N@ZURR910 diff --git a/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ab_stacked_transparent_light_holo.9.png b/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ab_stacked_transparent_light_holo.9.png deleted file mode 100644 index 19b50abcb536602cf2cd36d5a19805464988bd20..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 123 zcmeAS@N?(olHy`uVBq!ia0vp^QXtI11|(N{`J4k%PM$7~As)w*fBgS%&%9ECmdKI;Vst03^XH%m4rY diff --git a/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__btn_cab_done_default_holo_dark.9.png b/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__btn_cab_done_default_holo_dark.9.png deleted file mode 100644 index 5461b9c00fd3fc513aa4465682e70e87cca36a6d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 101 zcmeAS@N?(olHy`uVBq!ia0vp^EI_Ql!3HEv&)kdyQaYY4jv*T7lQS|h5*V8PD@dJb zGfWV2j%0YY@&Et-(u-Ft=sZxsVYp-gbGr;f^5z}?TUWk$0o2Ff>FVdQ&MBb@07WJt A3jhEB diff --git a/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__btn_cab_done_default_holo_light.9.png b/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__btn_cab_done_default_holo_light.9.png deleted file mode 100644 index 5dc6f804aea8ca344275ac6eb497b6bfe0f117f3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 99 zcmeAS@N?(olHy`uVBq!ia0vp^EI_Ql!3HEv&)kdyQd*uajv*T7lQS|h5*V8PD@dJb xGfWV2j%0Xds4&4P&{4SYp+J&{BRiiZ!)425)ejdW>;mdy@O1TaS?83{1ORBM8sz{0 diff --git a/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__btn_cab_done_focused_holo_dark.9.png b/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__btn_cab_done_focused_holo_dark.9.png deleted file mode 100644 index a70b53c59af769e3c98973ad9718670ce27259ff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 109 zcmeAS@N?(olHy`uVBq!ia0vp^EI_Ql!3HEv&)kdyQYM}*jv*T7lYjjGZ_h07hy7xL zS%<;BUsuG{45zRSgeB^>bP0l+XkK D`1l&; diff --git a/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__btn_cab_done_pressed_holo_dark.9.png b/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__btn_cab_done_pressed_holo_dark.9.png deleted file mode 100644 index 85d7aadd4dfb619883f68f1cc63e629698b5dab5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 107 zcmeAS@N?(olHy`uVBq!ia0vp^EI_Ql!3HEv&)kdyQbwLGjv*T7lQS|h5*V8PD@dJT z6Fe3@|6GeFPb#ATqtK84|Mweqan0i3X%}$jvMQLwz#trO`SaWQ^{znO44$rjF6*2U FngE5o9^U`} diff --git a/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__btn_cab_done_pressed_holo_light.9.png b/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__btn_cab_done_pressed_holo_light.9.png deleted file mode 100644 index f7b01e012f895bfe2c4241e1d48771fc372b35cb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 105 zcmeAS@N?(olHy`uVBq!ia0vp^EI_Ql!3HEv&)kdyQU;zbjv*T7lQS|h5*V8PD@dJT z6Fe3@|6GeFPb#ATqY%TTAPubyB?B2J9?cgAJee4pt{u!zH{AaisF%Uh)z4*}Q$iB} D0X-aq diff --git a/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__cab_background_bottom_holo_dark.9.png b/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__cab_background_bottom_holo_dark.9.png deleted file mode 100644 index d8f1c8bd54f4f091e79389603095c99cf825cb6c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 127 zcmeAS@N?(olHy`uVBq!ia0vp^QXtI11|(N{`J4k%Zk{fVAs)w*Gcqy~4zxBtu(zuW zGMHg-@7EW5UBeRx4_{GYv)%pQnG{Mujhr&UNqv-pZ`Il{xB Xs2c0@Tz2whppguou6{1-oD!Md5lfPH{+~ zs&ZK!$GJ#`+OXn)bEl7O^s7vMLr%~_eO6@BP#xDsWzJIxbKZ~=QHwoEqiCN;6|k~9&?6VGu8wVeg}kjlqBUkXd|o%rApJ7Xx?SmelE6^*`N?mP%?P7H@yM z@176Te{31>^aeVqCP$2D`iM8b&G*loT1#z02OAN3)TGUD#xbYXQgqexFre>@9yw_< zoN>t9>xRrEIA?_IE1YrUo=P<2hNadJXB=4rbb%a&IXb5^sO2P4AoU2`8OJ_N3+RuU z?3bPMlGWJT{|mv5xDeck3qc!^Tkv+yM^@uWqQKxnw{tZ6G_7EN(=@mR#5tHjEptZL zT?o!N^e&F18P*7EfGlP>S;He0o_$19Sz!q7up>N&hdzT z+KgUQr1}UkLQL4KR;yolWSqh_YPX?lMz7!1&pz~~fd%z~_Z{#V_yT+aKE`}mgO%s( z*Zy2en({y`_&;C`{0061zkwyNiuqzpAev$qeWYoU3d{J#NzC8IACaX$H=;%xu?3!~ z#a`2j|4di>P9KpnLiZ0Fl^vDJdHW{hJgNDYHbk!VsHwq51hhtobGl;RmY>GHkg{)E zesWUhFRGl6)Eh$fMU__)%@X*lTj%8LuWk+fh;ux9b*`$4|A#h$uKO0E`Tzg`07*qo IM6N<$f=1Pyg8%>k diff --git a/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__dialog_full_holo_light.9.png b/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__dialog_full_holo_light.9.png deleted file mode 100644 index f18050ea589eaa31233bc08e4f8a4e361747bc94..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1003 zcmV%vbFc60S)hq5aquQtN zO>~Q-PMt}eDy?tfo9G5^U3x~HVu{=o-l^#5`3AXbFq#7CZ= zx~R)Z%-PngELWXE=jG+4wH{HY%RHtL$z+_dj#xsD@Y&isDVlJd1j7%A; z{S3ob2!NCVl}{yrl8B^V**9f-6IC==^T()w$-W%VAY54pg(^F>UjitZxrB-eCn8Lf zB*stQ-rl}17K`6RG#lbS(&{_eIc1V`#=6_}di{5~T>e4x!ZPZXM|a{QRmt`XV*pbC z)5T)(D?{j2cRHWXf1>hHw<=z1GC@s9Ro2lk0Wc$?r`}K3Qx5<^GzKt(+iwt@SwZ#Y z1K3Z>bSEt!roEr8rydA`NJoVD>nPSV+2(05UE>4T005_GAOuI89vS#iG4B18N9tN{ z^Z@tNBTj+gCOB47*w+ z+2Hb~>!f2H1$Hq!D=_Sb+i%D|qnZ-1^bbIwX<}v&QHjdz0&e>kOOQ$(hHgzP5DjJz z0f>y6M3En>w55Wi4nf3bKUf4p>o0~xvY>6}4YBjHqH^B)8ba{Lja`ks{5OurR;$m< ZjQ=n8%sUGgc=rGR002ovPDHLkV1nUn!$<%C diff --git a/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ic_ab_back_holo_dark.png b/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ic_ab_back_holo_dark.png deleted file mode 100644 index df2d3d158e201f4b5bc8f478bfe194c819c762d1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 466 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6n3BBRT^Rni_n+Ah2>S z4={E+nQaFWEGuwK2hw1@3^B*n9tLu5dAc};Xq+#-xYx_sQH13|{`71Pj-*6Uoi`#n zE(U8IKgsQz<^Rb4R70ym$22iPZttV^?_#_6n&0#=x|;ZH&dfx!jETDzs(0U>)g_uQmUhGGNWo+VotE}_5b3Zj`hnf_E}Q2 zkoV^c&!VIWreR+T-g@7!2<2C~cxLXYh02~hOPyXw&7V2OC7#SEE>Kd5q8W@Hc8e16}SQ(iDxmE@S#`ha8qiD#@ zPsvQH#I3=p$s!-9K@wy`aDG}zd16s2gJVj5QmTSyZen_BP-2>S z4={E+nQaFWEGuwK2hw1@3^B*n9tLvudAc};Xq?Zzc+iX4P{i%w`)y*!lC}nMxxP5m z`ipDd|3l#c1q-`17wzs7jap-@cWTC&8}(D4%&X3GaM#!SkY4?Tswdc+PM~^5?gXjDEJr|A(9^w&s1cyzt=Kg=58+)D;SHpB%sRSHFHUToUy>RV`*x3 zp=*`d7Z@F1xvAFw#q#fW_g_%cHx(CZDFFIJwZt`|BqgyV)hf9t6-Y4{85kPs8kp-E z7={=cTNxTy8JPmPRt5&f_Zu#wXvob^$xN%nt--0uA|I$h5@bVgep*R+Vo@rCV@iHf fs)A>3VtQ&&YGO)d;mK4RpdtoOS3j3^P6 diff --git a/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ic_cab_done_holo_dark.png b/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ic_cab_done_holo_dark.png deleted file mode 100644 index a17b6a78920848c37a67246a76749b4cc1425a15..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 566 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UOiAAEE)4(M`_JqL@;D1TB8!2v z2N=7Z%(epwmK8Xr18D^?ZvQoBE&~Ijou`Xqh{y4_R~-EgIfxwlm><>K$vu5h!wc4! z9iP>XtrZVs65@3e-rKIN%Hh(x{ewWxt1j(s|L*kJ zSoUnickXv5=i7?TNH`^EJfpg4#&4;Y0qR0+drTg2JXGfUq3}Rr;{P9f_n*&gD7KkW z&D4IqLivGGRq&kmAH6(eA0`F~7S8rex88HAVS=03cY~80?cpzkFa4S5A6;t}xJ7Q# z9-saRVPfVT##U33AAO3A+Ypl|_94?@cK)tT4*8AF;-^j1iVm!a-M-<=iX&Itr@TnW zJpXO;4EOj9!Ar}#BHVL6_dHGGELXBQqN>Q8)gj~`k@s=>rw|ur?|x;upO5s^{asBY zKb@S=&SWDRsQzHyR;N3i0@8Cfnf~0l`P3PA4VeH(Ut{H!I{}l<<aB zB5gMTgH*M|HKHUXu_VC#5QQ<|d}62BjvZR2H60 RwE-$(@O1TaS?83{1OW6u*u?+< diff --git a/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ic_cab_done_holo_light.png b/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ic_cab_done_holo_light.png deleted file mode 100644 index b28b3b54f4c81d482f797f31936cbd4013c093b5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 552 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UOiAAEE)4(M`_JqL@;D1TB8!2v z2N=7Z%(epwmK8Xr18D^?ZvQoBE&~Ijfv1aOh{y4_S9ba-JBqkHTrZXEaifjpNYW7o zp-Ubd&IgJo2<&v8$G35^;Tskk#t2~^NlC?&yDV(Ca&uB1b9CBkO)cqrw|D8TKToRF zI(8j)Hm_*m)V}Gu(AmZ?>+lr!|Ew$fc6F-Mb^2PC^>5kCb?-yw@xD*CTf6%^rv51n zu|M&RMY8TuK!x`HjjgjxbG!Ig&nSGQ(EnVUqiU&qoaH15q1mNr`vuRlFlL+adKX`+ zs(G(GZ+*gGNpURMpV)N-wqLW)~-JKU!1N^uTZarp(au zRVr*pp2gnEY&GXI)J=?c?L+7E14!w(i?Kf2&j6te3n$Zi&Cq1Pnyg64!{5l*E!$ ztK_0oAjM#0U}&goV4-VZ9%5)_Wng4wYz$;u85o58|F#)LLvDUbW?ChR22(3jb0C6f zurx;QVw%w1wevX{81fiqT9$oZHH(4a215zM2{s3I28IOo7eJ#J d>KPlRN5&o6d@ywr|9haR44$rjF6*2UngC}HDAND{ diff --git a/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ic_menu_share_holo_dark.png b/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__ic_menu_share_holo_dark.png deleted file mode 100644 index 6bf21e307ed392bf00fe80b162a6ce9115e62c84..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 332 zcmV-S0ki&zP)h$s=>Sb2o({EW84x$2Sq@4Qvb1mj$j~;VIQBr2GX>%-APxay9!he7 z8W7h*gD?q**@0LXh%12j6cFzN;xHg)rA0Yl3bh0|IM)O5QD`2|BGz~0I$#-|1SL$5 zlJGbV2jtPKD8?58g7k0zp)`;V#9XwljI@z*K`Om-0V(CcdbDyt4~XM{*o)XuqGd@4 zDx{8=fp<=lEG6&%R0000-rS^s>8d@5ni2hppU0iV;YH8gwNa0%) z{Cz&}Jx|SbT`f+uL?986Pnf0|l@f5k0jz*^zeXXD13Pe$Xi*7R9^s5FmB7$P;6x!% z=kMH0V6IZ20v0@I38qpwTN6bU0_>(U;T<=GYX-1E8)QG}f-;!!681nE=wJ-aU=KPV z^-i_I3K%>@EawIsd5_!T)2R?x1}rE&N|%HcIQa;SqE5+gRv=Fy@M;YVKt`niqbhVk zpSlae%z=$G2Wp@TnqrmWnuKgf72^IDIDhdq{E7X5-;T%%62M`q*b}mOv3|8DyoG;R z;O#l^2#-VHDcnmy=|6xRPAT9SP9@+QP9YE&4z7Z?SGPkvc&h*a002ovPDHLkV1j;z BjTis` diff --git a/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__list_activated_holo.9.png b/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__list_activated_holo.9.png deleted file mode 100644 index 3bf8e03623c94b68d31963ffe7e59c72c3dcc059..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 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 diff --git a/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__list_divider_holo_dark.9.png b/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__list_divider_holo_dark.9.png deleted file mode 100644 index 986ab0b9746301f2dd9401829da09e00995621b3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 78 zcmeAS@N?(olHy`uVBq!ia0vp^%plCc1|-8Yw(bW~qMj~}Asp9}6B-)+^BAxRtXRm= az`@Yw&#rLZUbzUUfWgz%&t;ucLK6T(%Mo}0 diff --git a/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__list_divider_holo_light.9.png b/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__list_divider_holo_light.9.png deleted file mode 100644 index 0279e17a123f8cbb3c7e3a9ce5c5af8e693b6977..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 76 zcmeAS@N?(olHy`uVBq!ia0vp^%plCc1|-8Yw(bW~!k#XUAsp9}6B-)+^LX%RmN2q0 Ycy4A9FVZ~13zTN?boFyt=akR{01+Y(GXMYp diff --git a/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__list_focused_holo.9.png b/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__list_focused_holo.9.png deleted file mode 100644 index 7c0599e3a6fcce1d9b22e47bfdb63afb1d3d9c02..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 158 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqEX7WqAsj$Z!;#Vf4nJ zaCd?*qxs3xYk`6eo-U3d5>t~6?){p=$oZ!|i46oEul1LdSjZF4rt@IU_AhE`IYK8I wIB$ByaB<8!;4zVtCm{dd@wVRWcBu>u-xEd5&snyt0Gh?%>FVdQ&MBb@09FhvcK`qY diff --git a/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__list_longpressed_holo.9.png b/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__list_longpressed_holo.9.png deleted file mode 100644 index 3bf8e03623c94b68d31963ffe7e59c72c3dcc059..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 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 diff --git a/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__list_pressed_holo_dark.9.png b/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__list_pressed_holo_dark.9.png deleted file mode 100644 index 6e77525d2dbbc1673145d60d775602c85264330d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 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)} diff --git a/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__list_pressed_holo_light.9.png b/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__list_pressed_holo_light.9.png deleted file mode 100644 index 6e77525d2dbbc1673145d60d775602c85264330d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 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)} diff --git a/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__list_selector_disabled_holo_dark.9.png b/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__list_selector_disabled_holo_dark.9.png deleted file mode 100644 index 92da2f0dd3711a2ceb843768cafd6b91a2807b43..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 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|> diff --git a/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__list_selector_disabled_holo_light.9.png b/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__list_selector_disabled_holo_light.9.png deleted file mode 100644 index 42cb6463e4c28c6aeffa315c4fc869867dbb6b7c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 171 zcmeAS@N?(olHy`uVBq!ia0vp^{6MVD!3HFkzrK_Oq*#ibJVQ8upoSx*1IXtr@Q5sC zVBqcqVMg@oJyIHz9Y|%SiynA|kd)58s-{92FmHki*;@KxND!%;H%=F4ZU(n;yg$GVRgBd(s L{an^LB{Ts54)-;@ diff --git a/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__menu_dropdown_panel_holo_dark.9.png b/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__menu_dropdown_panel_holo_dark.9.png deleted file mode 100644 index 460ec46eb0786706610e21ac9097de489cedfc33..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 651 zcmV;60(AX}P)!1&^00004b3#c}2nYxW zdZ_-Wf*5)VugS&t+23J}V*z%DOHb#W|`Z#l>;cJ*L_P;jGoKD8nX4Z`xH*Q>s zTvTl`b;%gqS1znaOc|u@tz3t7=|UK<9Hr>BJ|D1%4AOYzE>c>YASL1(e+Y^`_iG?7 z1UL~EK(|`0e*W#*UXt~C{TfUweyI5sSBLVgO?u)p&e9+4(C=i^T1GuQJ|j^LdEE0 zfZFjzm@Nd117_`XxKDqSoJXh_wG-}tW_yHE!!B|TSvyio<6k9eTgoG9O0aTdZJ81x zmbul8Z%fpkT#Wc{ND1L@No&VX#iPVF7hx`c0JdkE;3e2%ZBQYi%Oe#dj=&z+_I>|? zOJi$dCv)FoZJG3n&>Qp|;vSo*JOkf=A5uR{`;uV-QwsX>Ho!a31HXV*se5TxFFA=4 zo=3!%#5;D2+DO|6R;c8b^-B2j{s4XhZw!t1m&l3O!HmBwHn=!)kb6yF?kI1MVX*Vu z<6hz)DH{^YBPWDzO$|0isCW3@P>L98oO;C$E5=4jGEPjLS?XZ=13IvJLaC?O;nLn? z=e?6_T^b`&$N3sK+o1N3^-DyB&=+_N>geY)_rHdJwBJ%s{^4(_WBZ5MLQM53U4RfX laXn(LVYMe-Njr@(d;;;gyUim^Wn%yU002ovPDHLkV1m`SB-{W1 diff --git a/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__menu_dropdown_panel_holo_light.9.png b/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__menu_dropdown_panel_holo_light.9.png deleted file mode 100644 index e84adf2d41604323cdad8b15e7034b6137e02425..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 720 zcmV;>0x$iEP)!1&^00004b3#c}2nYxW zd09!jyup9SJyH%;E_KZI5Ed^B*iNJmRSj zBG=jNc2B+cMg+dzb=~X>SwfDye{PH^oqQ4$1^~*55|NVv2=ckIR8XoEqC|oOgc2g; zEPA&fNb-^8#Mr1#v(VQn5UdVR@QAWs>EP1 zTHM9Zaim5tPqqk+y4R~ii**RWgPIHWkr2Q-rv~$oD_;OFg!*vQOJ?oR%RhjSvm}}N zU}~@)A@q_TOphE%y@J$^Y;2GXG*T-_?U?-%UNYKi5n>WcgjmBq)+~pV5UB*Fc4!_E zr<_OV^tE=(@|l_%K9#lBPBbeU!!Q72CYl{ozqWE(s>}kg*Xy-fB`%jskbX;(+jyxw zA`k(lb8|^3?6_RfL_?Is~gyeh`O%xX?U(f4nJ zaCd?*qxs3xYk`99o-U3d5>wYsbmTgqz{8?`Dg4L(`abqnuZs;wTVv8ZBg|GX^f4xE z5ck=nld$UVv7H|oR+P30etdkz&;0SSW2^3}yn7y4rozh{Dy3k((DE(NNCr<=KbLh* G2~7afj5MhL diff --git a/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__progress_bg_holo_light.9.png b/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__progress_bg_holo_light.9.png deleted file mode 100644 index 4bb22f0e10e621ef31f16100b3f682a09565c65d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 159 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 RY6Dcn;OXk;vd$@?2>^cl_{IPL diff --git a/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__spinner_ab_default_holo_dark.9.png b/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__spinner_ab_default_holo_dark.9.png deleted file mode 100644 index 29aff4d43f71a025f464587ead52aff2ecae6a58..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 254 zcmeAS@N?(olHy`uVBq!ia0vp^59s(?1)eUBAs(G?r*GssWFX)$e`(35Y8e@;SI4XCdOETn3puLX+U@Np z`{}{9$F@!!Tb4}GnD8m&^|D{1rP|_tuSV&+Z=MCoD&l+{? zpGeMToA<;$LF?@fW~rUl3#RU765DB+Fm*PQ+)k?pQ&%&Ye!A+gR)$OeeXHaR#_cxq xcQACD7BHRDw&oXmu9s(?g`O^sAs(G?r*GssWFX)$e`(35d_EZ~i&w|H<&_`ZD(+MedV5zj zu-#_I+lqbxCf!wDY`(!qq|2YPZ`s2sD|KqW({JG~4*WL+Cpx;A`7$XPF&b}JE9dda zdDh0P2cC5-%kKDDBus2)4y)97FmX3?+)izQiL;plcWMSG#q&-%rTF<%+zn>y2h*Mj yizj?!^E*(P`ureMOz-ZiFXWg1cX%y7!FpSm=AYI1UI{?QGI+ZBxvX9s(?*`6+rAs(G?r#o^TG7xZ`zf?Wo$i4qI|8=SuS_>z)W_YPj?%Q>u zIp@ANM{x}Zqe@#*i-Jc_;!9;KcT)!P=e8Z65pgErb%iKSkCNb@A?yTt$n@r z2c`IHF%KKu<@hR|E_CSLV|hUMOZy3b87rAYm)KaVUb9s(?*`6+rAs(G?r#o^TG7xZ`zf?Wo$i2t+|9e$2v=&Zo&G1s6+_&pQ zbIyHljz-QjH&*S{-J;(gu&3N>@$LMyenNedpai4+B)&;SOq0|eu$bkReVyxuhm-Z9>GFCF_99MaBsxVXw=u8GrS3j3^P6KmrqN>Fc^oQq;b>Mt0(a$ z!tgX@A7RK4{kGy^A3#w21maN-UfpV|U0)B)Mu)Zk(%$xiP)OBD#retJ&sicWsshEL!WHUI0Z}S=i2Rqw=-{<_oUlU4$I1(Vt^KG}@Sd2k4!kUV zp9d;G14UN$xn@Z2Tv!X1WCiPlZi?T5Wo`s>dMMw4?2=HB&MqLoAdzh3Gg0e200000 LNkvXXu0mjf#CNP@ diff --git a/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__spinner_ab_focused_holo_light.9.png b/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__spinner_ab_focused_holo_light.9.png deleted file mode 100644 index 6536ee63329bb47bec2bf2384aa494923cc2773a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 424 zcmV;Z0ayNsP)Km%mHHKmbPH_0G1~QE(|Z z3L*$mIy*=P@!u2&!BHHFf;fuc0uio1*2@YRBct9{0AyU2}iGVkcWw7UUPW(q{Hz&m;6;CQrhm;h30w)z2(`W_Vv zws(S3@Pah`KM=_o2%_3&n+}O86bq(Ag>`_N^4m7drC>+{^&N;72|01L0Qm!AONf3s S@;8qF0000Km%VDkFce0=d)+vOWKIG} zhpvGvb*AhYN}o4m@H1o!d4o*tRBGZMkUCTWmkL{wB~SUlAntIEgw4Gc(!&*+NcHqe zdbonr;tjwaz@#r!B?pk5-j_#K1)p#z)*b-3QShBfQxGf+4==MNa*z{HXhG0C1P_4~ zh;-k(7eP#tUz1`!Wij$Dh)MD;xve&Fv5GXEp_kweUysY@i1cm8S?~wm($ky-rf?^L z4cuB_3%3%uz>Nj2a3et6#z@uGqTe`wK1>2-pyo{<@B~f=x)vOqS_S8F z{BbGcPm`Srko*>0TM51dS0?bbgq{a9*ucpHu=A!M^DM~~^Y@aViMI>L4{MrZFUa%^ Q4*&oF07*qoM6N<$f+pdR_W%F@ diff --git a/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__spinner_ab_pressed_holo_light.9.png b/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__spinner_ab_pressed_holo_light.9.png deleted file mode 100644 index 6de0ba8841d25f20f12e14002ecc4c9ec6a7b2f8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 370 zcmV-&0ge8NP)Kmp@CxKpa3{epU;uAYD{w zoy1-2XXsG+d5c4J(@pInLg`pK=_I6J(k2d`5V?BE{Yj@j2pl)OcgK;0qd#7akgCKEJ@PeExDlrpx^Tf8?8gJ#K-Da<_nm z+&*9_w+lGPs|OtA)dC)JfQDKAb-?t#>nbk~ygr<>n4NOeOiNA8R)UE3F)|0PZr-`P z{wS3Lh~%_Rw1t=h$DO2-+|>0Ilo0LghZEP}j*Edw;7F{TKbM3p1iOHI0}cLp61dt? QIsgCw07*qoM6N<$f;wQ9<^TWy diff --git a/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__tab_selected_focused_holo.9.png b/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__tab_selected_focused_holo.9.png deleted file mode 100644 index c9972e74bb4fc7416960e238afd47b1ac363e316..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 148 zcmeAS@N?(olHy`uVBq!ia0vp^EI`b~!3HEJ|NhSh5-4`^4B-HR8jh3>AfL0qBeIx* zfx8og8O=|gUJDd7^K@|x;h4Gh+(zC520Y9MizoD2>~^~(JZa^V pUoEkkaeSh9w)TUlKa6vZ+qJ0**((%Vy8umK@O1TaS?83{1OR&wE2RJc diff --git a/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__tab_selected_holo.9.png b/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__tab_selected_holo.9.png deleted file mode 100644 index 587337caf74f9ba3d32ba1c7cc8fb8b0b5ba245b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 151 zcmeAS@N?(olHy`uVBq!ia0vp^EI`b~!3HEJ|NhSh5-4`^4B-HR8jh3>AfL0qBeIx* zfx8og8O=|gUJDeo^mK6y;h4Gh+(zC53JlB#xw8$}k`45e4cLk;e3y7!_%!uv(Z^d6 t0#9x~Qa^f(Id{#0H&;LIP<)f9-+fKc+F|3Yl|VxnJYD@<);T3K0RZ_tFJ}M% diff --git a/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__tab_selected_pressed_holo.9.png b/android-libraries/ActionBarSherlock/res/drawable-mdpi/abs__tab_selected_pressed_holo.9.png deleted file mode 100644 index 155c4fc753ed43185b31df3bea2af1ea5b3e7482..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 150 zcmeAS@N?(olHy`uVBq!ia0vp^EI`b~!3HEJ|NhSh5-4`^4B-HR8jh3>AfL0qBeIx* zfx8og8O=|gUJDeo@N{tu;h33haPQZY#>U2n_RP$O>mRT6my}r88lS< uMnfl1c4A|rBX^f%!~&s(1*$LFm>5oL2|PB@cz*+E5QC?ypUXO@geCw>u`ROz diff --git a/android-libraries/ActionBarSherlock/res/drawable-mdpi/ic_launcher.png b/android-libraries/ActionBarSherlock/res/drawable-mdpi/ic_launcher.png deleted file mode 100644 index 359047dfa4ed206e41e2354f9c6b307e713efe32..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5237 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 diff --git a/android-libraries/ActionBarSherlock/res/drawable-v11/abs__progress_medium_holo.xml b/android-libraries/ActionBarSherlock/res/drawable-v11/abs__progress_medium_holo.xml deleted file mode 100644 index 6bcbdb83f..000000000 --- a/android-libraries/ActionBarSherlock/res/drawable-v11/abs__progress_medium_holo.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - diff --git a/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ab_bottom_solid_dark_holo.9.png b/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ab_bottom_solid_dark_holo.9.png deleted file mode 100644 index 575334699663b221b5a2b3251572a7c7a23ddb4a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 165 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nET98VX=kc@k8Z|>$jV8FrZ@U7ta z-*T0WQ@><>I%v71J%hiqt0P@2{q!E)%~9Ermd_VC*s;IdoBnhS>rHk6>|lcSgpVF9 tjEp}SQ%vGx1w)$%c)I$ztaD0e0sua~Gttc^?peW`&R>iA3bc>G)78&qol`;+04`QPF8}}l diff --git a/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ab_bottom_solid_light_holo.9.png b/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ab_bottom_solid_light_holo.9.png deleted file mode 100644 index 8155fe840532e1d0fc25450729892ea73c4e007a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 166 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nETTu&Frkc@k8Z|>$jV8FrZ@J;?q zbcL8uwC8*^`8m#29p5Ib=%`p$wC&7oqt#odO)b{rdQv>$UUk^Hs0pFVdQ&MBb@0G6aYR{#J2 diff --git a/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ab_bottom_transparent_light_holo.9.png b/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ab_bottom_transparent_light_holo.9.png deleted file mode 100644 index fa4d76af93de31de153c6a7d41c05496bb14d2c0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 152 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nETcuyC{kc@k8Z*AmdP~c#3C@cDZ z^MXtGfey<_%m2nWx~HUtq@RtOD!V+x#J|ag^QD{sZZM%<(R`m!o+Hzd-iC%RO>bP0l+XkKAqp+G diff --git a/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ab_share_pack_holo_dark.9.png b/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ab_share_pack_holo_dark.9.png deleted file mode 100644 index 55099d49db309d03035101e55e64396b62af3054..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2875 zcmV-B3&iw^P)KLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z0001HNkl)K_>U2H>f)F385FtW@2uXtEe@nD6oEa_v00960 Z0|2By^PX-KG@Sqd002ovPDHLkV1g_UPeK3y diff --git a/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ab_share_pack_holo_light.9.png b/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ab_share_pack_holo_light.9.png deleted file mode 100644 index 3c4701fc21a7b70310c0fb65f82c96406bf676c9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2869 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 Tx*zQx00000NkvXXu0mjfH|R+l diff --git a/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ab_solid_dark_holo.9.png b/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ab_solid_dark_holo.9.png deleted file mode 100644 index 6622cbad34409b2e09f69e305455482ee107baa6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 163 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nETEKe85kc@k8FK-lVFc4sN{QB_B z&fog}EEk$2&*T)$|Ch61%h`96?xa8O-xitu^~t0=vn)PNZ(|U lO#br3!H&B!tiEU`L+e4N?emv^?*rP(;OXk;vd$@?2>`X4Gjad` diff --git a/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ab_solid_light_holo.9.png b/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ab_solid_light_holo.9.png deleted file mode 100644 index c4272978338a232aa445ed5190abab61afcedb16..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 163 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nETEKe85kc@k8FK^^+Fc4rl_yt@$W?82D^ReIqPjo#d{bLmpkiN+x lnf&F6gB^EeSbfn>hW*nwPPt#_849$O!PC{xWt~$(697sdG9dr} diff --git a/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ab_solid_shadow_holo.9.png b/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ab_solid_shadow_holo.9.png deleted file mode 100644 index d0df29d8b3fef9f71cda9b7a0975c68dcfb05685..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 290 zcmV+-0p0$IP)(^RAa&-b-qmfdL= zKY^DZ_=R_1v^+>Y{!mW=MF!v|2#Q>Q>z_&4i6T94j-Y4q`P>I~g?cE`S~^QhBCU5$ z-8a`dJ38hrt)qwm8XJx0+%VAuW=z7Jg@`1pBAUrf#Ef=wZl|UqH7RO)u1OwK(@xK~ zuV&5*5lN0GQV~igR!o15*n1TfDTP6ilQ72>QBJOyK^2jQYHlAzlrUMuFCtAA$s$=K oi)4{qME3aCu~lSF#Q4a(0o}otDK%H_Q2+n{07*qoM6N<$f*T@rc>n+a diff --git a/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ab_stacked_solid_dark_holo.9.png b/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ab_stacked_solid_dark_holo.9.png deleted file mode 100644 index a0d9c1b957ea4a6ce62abd120668610d0cb2bd96..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 163 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nETEKe85kc@k8FK^^+Fc4rlxca~( z?t=fRa*SINS}wBuewp3mefy2x$=b4i8MC*B`RkorJG1!P69>HDUX#kpcm>9d6MZKb ky7}`x**qcrtNL{AY0h>p*ZiBQ0JN3C)78&qol`;+0O3wK)&Kwi diff --git a/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ab_stacked_solid_light_holo.9.png b/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ab_stacked_solid_light_holo.9.png deleted file mode 100644 index d36f99fecf223779432fb843b823c04d739f05cb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 163 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nETEKe85kc@k8FK-lVFc4sN{Ca;{ zvU;8e%Y`P%GdTtG|K%*$a`xS%JL%8+w?$@ueKP6JEX#C%J{El7iLS?_f2=|R(l=Qo klfOK1u;Z=_t1sHgP`H~Vw5GX>6KE@gr>mdKI;Vst03NU~l>h($ diff --git a/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ab_stacked_transparent_dark_holo.9.png b/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ab_stacked_transparent_dark_holo.9.png deleted file mode 100644 index 5ad475dc3f478734be31bc5763ff494e5f120914..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 158 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nETR8JSjkc@k8Z!P3yFyvu&IDfHo z*MFzV3!h#&I<8{wJG6*7%`^0A*`zgvpO3}4Jy+2bzzZhGPxw0F1DlG16;n~mnRAu= eo1*Vq{$#i=98+;OAz%&ALIzJ)KbLh*2~7aXVK40f diff --git a/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ab_stacked_transparent_light_holo.9.png b/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ab_stacked_transparent_light_holo.9.png deleted file mode 100644 index 6ade5eeb37d8388813cee512f8adaad0f6c15397..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 152 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nETcuyC{kc@k8FE8XhU?9M9Fk3-& z>Hkf73eN%?4n{M7dy#!$d2ZSCCv)eTUt5@6!ODmi{A7$QW>Hb7V|gN6#Q)yLqkTHN Y-hRf#&+ODnfL1Yhy85}Sb4q9e0PNo==Kufz diff --git a/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ab_transparent_dark_holo.9.png b/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ab_transparent_dark_holo.9.png deleted file mode 100644 index 719b9234df6fefc32c628a212141681df3414d85..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 171 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nETB2O2`kc@k8Z(Za)puoZEAojv! z?q20mzFS+?F-&~oGw)ovvN+_p>pJvXn6S<7W@Fox#)9&t;ucLK6T;ku_WZ diff --git a/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ab_transparent_light_holo.9.png b/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ab_transparent_light_holo.9.png deleted file mode 100644 index 6da264db26b5debc433e570e454f7ad596d3609c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 160 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nETbWaz@kc@k8Z*Aml2;gwNxP9_w z>q*543$-17oYd6QwPclDxvFIP6Y06uZ3-`2R5T~}Ha6e^YubHkRDB$o9=Xj@xc>Lb i$;LIUf5PjFDj6>?G+3v-_OK(+N(N6?KbLh*2~7a3Fg*4E diff --git a/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__btn_cab_done_default_holo_dark.9.png b/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__btn_cab_done_default_holo_dark.9.png deleted file mode 100644 index 7ef2db75e273c3a4fa34a867d43714d47b67dfd9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 109 zcmeAS@N?(olHy`uVBq!ia0vp^tUzqR!3HEvyN#v+DHBf@#}JFt$r%|L2@FmD6{OlE zCs-P=E^ay;FECBu-~a#X*$!!Fy;QT1l2!H>nDyu1;UEQuS2t(=%(&d{0o2dn>FVdQ I&MBb@0Ph$gIRF3v diff --git a/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__btn_cab_done_default_holo_light.9.png b/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__btn_cab_done_default_holo_light.9.png deleted file mode 100644 index 2283b4c01f31c24c241101989a028a28e662ff2d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 108 zcmeAS@N?(olHy`uVBq!ia0vp^tUzqR!3HEvyN#v+DPvC;#}JFt$r%|L2@FmD6{OlE zCs-P=E^ay;FECA@!GWvmzw+t@{SPuqdTbmsKKbP0l+XkKVJ9JJ diff --git a/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__btn_cab_done_focused_holo_light.9.png b/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__btn_cab_done_focused_holo_light.9.png deleted file mode 100644 index 3c909b51306d684dc9fc4deb674ab1e1feb7004e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 113 zcmeAS@N?(olHy`uVBq!ia0vp^tUzqR!3HEvyN#xSIG!$!Ar_~TGcqy~7@GboNVOeo z`FL&lz5>PtO@Rj=>T@VLG&w|ZbqQ*{RI`whRrVK{_2=K=E+vL!&S{*=@1z8QW-xfV L`njxgN@xNAaNr>U diff --git a/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__btn_cab_done_pressed_holo_dark.9.png b/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__btn_cab_done_pressed_holo_dark.9.png deleted file mode 100644 index 131d1030c9d5b447ef62fc8e336d9d3950ff7519..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 115 zcmeAS@N?(olHy`uVBq!ia0vp^tUzqR!3HEvyN#v+DJxGG#}JFt$r%|L2@FmD6{Ok@ zwtT#{-1s4r1MA|Z!|?(x4J`lv|6k8`NJHzTnuV0CvcJHrKmQJQDKT8Re5&^Sxg#LM O7(8A5T-G@yGywoD=q9NE diff --git a/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__btn_cab_done_pressed_holo_light.9.png b/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__btn_cab_done_pressed_holo_light.9.png deleted file mode 100644 index 3e7dcdfdbaf66d51a90633e6f601bfe71b0c5069..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 113 zcmeAS@N?(olHy`uVBq!ia0vp^tUzqR!3HEvyN#xSIG!$!Ar_~TGcqy~7@GboNVOeo z`FL%)@k1sD*2PVS;{{wASQ@v8h$x3#@+~m2a+{}M^7C)Is4GMKie-X3Pa7xz&0z3! L^>bP0l+XkKapWP} diff --git a/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__cab_background_bottom_holo_dark.9.png b/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__cab_background_bottom_holo_dark.9.png deleted file mode 100644 index 0bd09806f5c85ad3a33ec80c2a526e9dba34d1f3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 166 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nETTu&Frkc@k8uN>rTFyLXm;P>R{ z?#-o|?nQl9Ua&YVWQl+9{Kh9CkJo#*NAA>4+xPwD`<&mEu1}vZI664|W68WNxRjX* q7uY2C$wZnF2qKv(-xu6mlE@I5@4DcHNa}B(#SEUVelF{r5}E+w(lnv~ diff --git a/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__cab_background_bottom_holo_light.9.png b/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__cab_background_bottom_holo_light.9.png deleted file mode 100644 index 43ed26d4784aa508b93551bdb0359b959bd2c91b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 161 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nET3{Mxwkc@k8uUzCjV8Fq8;LR1* z*j37dP53cYgnN@8iE~W|ez(m3TTj;06C0 vR9@;$usQD^o~Q2-Eg&#Ke!|DE+S9qyz8u@<_Da1C=l}*!S3j3^P6YLYC-!V(AVEFG+v!>way|q9)89ZJ6T-G@yGywpFG&bP? diff --git a/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__dialog_full_holo_dark.9.png b/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__dialog_full_holo_dark.9.png deleted file mode 100644 index f4970ad1c3278235157ac72f71fc98f159fdc439..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2159 zcmV-#2$1)QP)7pj*K04R=GS>IExgb+dqA%qY@2qDDdSi?}MdX75WMJ|ri_~yampZf~b zyDwJPzURp0aERFLx!K0Z6`{S(+b^7Rq0fZm(kDLm@P!|`&m~8kF)y`OQ+*6SLgj(n*c6WFZ`T<6tC6A%w8 z+L+Kg_>sWYRhaz=AtQLA^@LuUvKr4zS(=h&ATdHMd1uOv+V9M9YYe+zz%fKlM3B!~ zyq*EP{ZyC9dltDoQc<8ZrM^eE_Hte#g^dKR2>{;+o?xX#_XJ<6fcSW3 z(2+n3e1qrFpfvl1x~?#Fy4|E$M6lRgKuT?d8dD>b&VB465lv_ms575+OWy%#u@k+N zI%?Q+K~hGrT_7#|a=gF%@ZrOc@87@w`1bAFU(2$bW3Gd+|4`xmgT=9~$+>Rd`_AEe z?tAPdzh~^4zVA1WkB@)c-QE59<;$19v5OvFA}vv41E1cCHa5&@4N;9-`R?7jpWeKA z^Yg>QL%m+FvDt*4cRX_bt0?zBkB(K>DX%%#=N+5R(_-8y- zVb>j!?$Wbc5y%%}IfCs9*+@_USOKV3tJQDczI|KW-rgqvI6{s^UDwxjUH<~$ckEhw z$wzfwA%@V6dv=Zxn=8;sa(#b)ziOIh-@k{Dz1VCvD9chBW?(0HZ$3-*gQG?|lNRhy zsce!AuP~V46@dEg?(QVrAwo2L-=l3?V9=qSyONQk&Kv_~&Lf1nMm8E$0BV|mEX9~d zNP}Lf5}1xu21h4T$+9&-HQuut%PRmY8i6duXoOerBY}OxLGlJ5BU$zc%^yh8OvsW{ z7(^}+!OmYLNsSuWi7|-^5)oDyq5>gHA{u-eOKk`#f#=$OmM4_(@m{kC%_W5DAmmhR z=d>`52C;YCwuB;r{%j}Ebe_P7K+b^`h8A8*tydWpwYtuV2y(IKDEl%UBLZ0(i3V1m zfUn~Tp;05RlF3Ax+6Y;a8pF(Tjoo`iqE#Ca+!sAl5kbmO&cKL3&H*nkK%{gluy`-t zg(lV{G7z#PI)C*NX293=me{C~cPz9KvLxQ9W=NZ^Ugspsp|?>vp+=TQM}wGdXLXG{ zVi`Ci0$G}v=(F^hV}w+)Oe2t`iJ2g)`#yKX$5zN3ft&-L4rl3d-=WWF22RL{IarUJ z10V#?jlh->hk8-+(B={{f_KC0$_Y6UbF}H| z)iXk95=}<}9Szz&zBnPrq{TEU=*R&0y55rN8c7*TmhI~1gq#|$ON79_OO5CMyD7gV z9}@irgLxzpwBV#1S)NvH5*4HjnIZdKqfiE}-PZx=`o6zC@DCwmFGlT6G>P~~(uABG zK}Q3f7d(yIx@nqEUDtg*;O`-1HeJ_!ZJOp2fHih{)cJyq3PN^{5b9^?iHmLcxw*Od zt7)3gecv~S{b_{c(f57RG|lImo14Ed?FxBAs6Zqt*x!B;W5{pK*JF7#9(y&G-;L+K zAIl#wtZ4Xp+<&dElXaOZRbPeOuW5VVgIpFOP7$z(T3Yv~vHW)|AI5VJTZ64^6BEBSg#y zGM}I)%~}j17KiFDEnOcuUt#E@>0HCEcF3*~0j6Ce`xZm1O5Ih`IeuTN+ty1RWW4eh`~TOU@&BM)3MkQgMM@bdYm8B8c#1 z#@ViWE78D40!D<(#Tx`hXJ-KSDrqoae31hLi8 z$z>DjeP}^jBk1AK*j$2rhW(rzJ{2JYJMmiAitr^tE-^SXloO=ZTOgN*_a2ZHvyBd7 z1l@JghOv{s(P7lwc?A9CfSo}^z#H{B))n$biD&`>gkS9e;$0Z5~J8tXRDNuF002ovPDHLkV1mNB_TK;i diff --git a/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__dialog_full_holo_light.9.png b/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__dialog_full_holo_light.9.png deleted file mode 100644 index 172fc3b5e3caf3357e706be2a1f0d91f357c8e5f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2302 zcmV2ok^m97efLZMJ76bgmHN3TVPgynL1iZF^o zv0AMLkI|bD5@Z+S7;_RWD$X2Q#-Gi>; z=tN2`078B~PH0>efZ`B@1i||(&~g>qMGRTwTrQXXbnj39hPAQB*)bIg_=HbA_WGzO zR;yL=j9HSDjSEl*;KYv!A@o|O_=;IUA}l9+ObGitX|Dzg#M7mV*iktr2nZlVbl%^^ zH53Ym36TIhGR!|u7{3PC~!L=Y2z z32ZT8B;zY)i(nCqF!62X25hwu6@!!-aVKznAwf{$S4ay%(<6lhDJ|l}=KVE%xD;tO zjxokGV%Vil6ww-?fi&aiwtz1TI;KLw!36;9iSC?$w}w5ZTIo^H5hBZ^Apum+pFjWp*|TRqUSD7TX^iIhX;RaeQQ zE(9uq^MWzvYwRam(2Co38gn;jAmP?U& z&MGvUhjxmcRMYbSg3kR zZt4g}LPgLEq&hYm(J$si0u;4;IwvxY6?fp6l#|X8fH;pmq-q5ISi1H|(Ge;Lg>w@fkyi)P5d7;2~0$MDQ@!DE$`cg61AQt41xJiqTo9Dlsio7bTA}sD9BZvH#!%wZ zmJ%ND@1^DnZ%X(Ld?$$A6k0J~NE59ixD&!XX{j@~=b>7mwKZvxCyp*B)cAo?C*Y0% z?1kZeY?X^e-9W)XxdpU^5OahW`IAUpYa}@W?W5#&t4q8l2swcYLBS!VH7P;dBP@_? zQAk2?GdMjs_n0oBI`TV#(4X2ifxe2hDg*@upKxQ&K(mtAk|`HJPz)_1HaAZ&&GHf7 zsz6IO?f{EsSe^=LZJ-DtRGZRNi3)(P24xANDG)6Gj(#dNGOP_9D0K*+?F8HR`Nj#&1(CYoj<+oYNw{1t4Y0L^ri-RBp`1VD6hPVuR0IkNiMUb`EeV02O|F6c zauGd$;Lv5&C{!~b&}Udb7lOKhLPE$D=wt2>b>Q`^nt&r(EH@_=La)06a5Fwnfw+Sp z&{C)%=8X_pC077s0o1}imRwSiS1dcYq8ac~BtElCsZ+`Ul=zAmLOFfPAwvBY@Kn$$ zk{zOiq+$R>LAX{rQ>;#)$VHAb@IJ99w*HlMq6mNtA~I*7`@~Y7+@e^8prDZQ`Pk}@ zSYXq1DD{)3Sw!SFBRAo~AvKngUU3Lg#cu0$<^+@bU0;P_H1st~XDv}F6a(QX9$Rbi YKbh+rFQXz7g8%>k07*qoM6N<$g2q=E^8f$< diff --git a/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ic_ab_back_holo_dark.png b/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ic_ab_back_holo_dark.png deleted file mode 100644 index 8ded62fb7b6a27a86f7b532c9a2b5a4ae999d34c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 741 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UOiAAEE)4(M`_JqL@;D1TB8!2v z2N=7Z%(epwmK8Xr18D^?ZvQoBE&~JOTTd6q5Rc^#N8xy%NgI}`eR{7o3SVw~oLF?DlhO#(rS&-V`^Q!s%)gPgzJD$(6 zlPX(2b^RHIj&o60rR$>g!|G>TRxtl*e|^4a{T&6ax|r;1#_KA};b_owfAXfrk8RFR$o&QDy{Vn>#x#sulW#~7Jq)- z)TH!~FS$Xsf0AE4joN$h`JQ|K8Rwjx@86b-rgDVb@NxHUL6S>yvXNP=t#&QB{TPb^Ah ka7@WhN>%X8O-xS>N=;0uEIgTN160J|>FVdQ&MBb@0GkggF#rGn diff --git a/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ic_ab_back_holo_light.png b/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ic_ab_back_holo_light.png deleted file mode 100644 index 517e9f72d0c8d28a22360ad5d73476c25fd4db33..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 661 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UOiAAEE)4(M`_JqL@;D1TB8!2v z2N=7Z%(epwmK8Xr18D^?ZvQoBE&~JOTu&Fr5Rcj%_$5Ae=jmr`i z3DvOQxBn=~BCIDR#iS^(^w0Zu6&JUPm!vIx7~`u}yzledo5s8M7#uS86ZssvI8sdD z&xg3?2M7HpA7}46mr}+fqP5gidGgVwQ1_}WN$aob&9(OVStj}6Xj_!ShugM~J~IZM zU$@KD($sJ1b4JGMs?Xp43SH*aH+p$-+40a@k*+<>G~DD-|-{tS&vG^x*%GGq=j0Y+3zJN#Vil?OA~@ zukBM`R53;FYi;h*X6Nv`Uq9z3iuI~5j`7&H`BAcUqjcZh^7x-d8^2$_pe40Fq;EPa z%hqE7x*0h;3a++#0KFc4?e_Zv*^k$mEo1DpzWsL9`(v*67M^+IpR-MVa>nHwC6*2c zw&pTkoOQ_aoMO7bofkh1@}JI}ZKA~9;BBq7`S!))DS4@K0yY}FSDK>kZ?)HK*JGG& z7n!~MQ}4z!!HZux9M^8s)pB{g?A$cwGrvCg`RlIwI(LVEXW4OK`|IMz?e(5Emfz@% z$^^!kYKdz^NlIc#s#S7PDv)9@GB7mMH89sTFbpv?wlXxZGBO2ntqcr|?>AgV(U6;; zl9^VCTZ2=RMLtl2B*=!~{Irtt#G+IN$CUh}R0Yr6#Prml)Wnp^!jq{sKt&9mu6{1- HoD!MOjfK$EgnR$;T z=N`Kp(hSrM@CU%evd=bf=-4w^bQmnuhmUH-jd<6WZ; zHl4_>Rk2U@t}L_t|AiwlQ891B3C|YS1B^O3M@oxo5*z)LB91b?+QOQX_r0yH)YX2= zvK_aW4}ZVF|MIp0)1X?{@CS{e_APBtKk;H~nV$PVB{N8HV+L1tOj6 z``KDz%d4l`HAyHPxAByb%b6xG^S8m<-YfXS7v>b+zlZNGcwheZcvv-P0dQ7=MviH9v^t)=yc559VF`j43j z_pMt2oAX|`goy_Fm~UMa9d%t_^^2qU)cXl;U0e%IRZSM> z>7Ksk_VioOmKv*1mN|c~ELg&~mMikt+LpAdYoES)QG3#uo404uV`0ytJ&!XS^rKz< zU6j9{ob*(;{k73gyQmwdmG2d+82l2_J(5-Z=Epp_^THpe+eb5HIvzUo?fW(va5{7P zd0GD0trC|9zjsRjleub%YeY#(Vo9o1a#1RfVlXl=G}JY)&^0g*F*LI>FtRc>2C}UT z3_|{Y+l-q7HAsSN2+mI{DNig)WpGT%PfAtr%uP&B Z4N6T+sVqF1Y6Dcn;OXk;vd$@?2>?&0tquSH diff --git a/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ic_cab_done_holo_light.png b/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ic_cab_done_holo_light.png deleted file mode 100644 index bb19810bc2062509e4e4968099a359ad73818728..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 915 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I0wfs{c7_5;rX+877l!}s{b%+Ad7K3vk;OpT z1B~5HX4`=T%L*LRfwTh{zxw0jNgl<&3j(^ zeD(x}!be9sh1LD$__>xwFX-mty1-MRJ?GVgBPRYo&#phmts!D?ltV3&FI%+a$=z1Z zV;YHl1iMSDgJ+|>#46F---v^ z=n46F|IdfFb=)S0I4Coo@!g}n4Nex)S*)#RZPN@k9D49tzo1o|L;8h-cSg(aGrNAg7qQ^lmAJNnY2BwD zmg$yB$_Kc(9`bFT@$ln4rdg7D8~IZ-f3I60`0mq%qw5167@Xn!BqR{_Lfuy~aYE2x zQ4_Q6{SU<2c z;lT8&TH+c}l9E`GYL#4+3Zxi}3=9o*4J>pG%tH*#tPG5-jE#Y8D+7a&|KB#FXvob^ z$xN$6(O_z2Y7RsY4Yp<(!9Wd?ARB`7(@M${i&7aJQ}UBi6+Ckj(^G>|6H_V+Po~-c P6)||a`njxgN@xNAiwS~- diff --git a/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ic_menu_moreoverflow_normal_holo_dark.png b/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ic_menu_moreoverflow_normal_holo_dark.png deleted file mode 100644 index a92fb1d4af622cfad770d7c494121719a7896e61..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 167 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=d7dtgAr-gYUQ-leFyLX@@b&p` z%gbN)&SLHDYV<0q^J4_6fq?|&@*V6j4#NRakTDF}Z~@#RP$drMna{J{ZM0wU(H|t@ M>FVdQ&MBb@0L8N*<^TWy diff --git a/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ic_menu_moreoverflow_normal_holo_light.png b/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ic_menu_moreoverflow_normal_holo_light.png deleted file mode 100644 index 930ca8d95e8bee5a1240fba645d9dab919abd734..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 184 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=^`0({Ar-gYUf;;epuoZ6aJO@& z%&D0-IKvGL&8p&qV;O7KuliPO1yl(K>(rHwor_8Hg9|Y9Gj8!^hz0Vk4~QZ}ABcvv nF)(akj$uTI?LshtEWgbR4Rf6*RPme*0Ev6L`njxgN@xNAEX^ml diff --git a/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ic_menu_share_holo_dark.png b/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ic_menu_share_holo_dark.png deleted file mode 100644 index 45a0f1da0d01b7c0ba53830285c67d629bd0774a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 699 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7T#lEU~2MoaSW-r^>)^McjrWjeSoS8SCOEBs|%|?VJ7D=T9Yz_dLJ8 zJ9zK=&-=vhubx}{vF6<8-!m`2Et8%6G=f2_fi-~)r;kY>>MAgRkm@i7CT&PKJ^T(I*&Av>d6O5U0r~;hkX|;LrY6t%e!5sze0;lgN zzhmA1v9d1mdTWRDgJXqP4j5dhQr@DSSRpJN-*(9Bjp4$N@%tt%vt{r<#9TCmVT&q5 zPY_dpf5x8W&TrHi1EzgwuzL61gP~v}`*h7_ev9YX^%66WzmeOz)Rwd1sPzfWyZX+; ziqW^(w(Z~haJj|{8OsISSA~|G@%CQ8Y_d#7=yl$KAFm&t%#H|W$kcQ2;yBguIO76W zkG?He)AQ@KipLqRU6Nb%FPk$;xS@jW=|$x{C80dl?QT)`*~FQi^@N=fie6YGbN2D| z=`W4NG-chmgqp9bsxquQQuyVroI59@gwb7QnV5NMi~&p85J-Uv+l!N+#T%5W;<7yr4}f9Ow$JGA?da_{7}kE@t}@ET5LG{B2CIDTQC8`Twj U_qmZcFi|piy85}Sb4q9e0Mf@O?f?J) diff --git a/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ic_menu_share_holo_light.png b/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__ic_menu_share_holo_light.png deleted file mode 100644 index 528e554abe239137182dd9069d1fa4ba02a109a1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 935 zcmV;Y16cftP)=+L@6RIMT%_@p^A^X5UDRjLANf13Pq%);A`Pd+=!;23pXx; zAif`nPef)@LW&ftmV!!=U?`shr5Kn0)zPywg_Q~)Xf6@UsrA5Be7{a=6EByPs``206cpncnr4<@!q@mA~gUzaA3%HTX+%kDFHYT5Qf!vm`Me|1djAs_x*GR z&!z%kGhWI$<|3X<1;9qUl5@-=4yFR&S{y_@$C%@oE<1op+>aXzjC~!)$_ii$_F+%K z@y9V;#ya3q+!Mu4ce-D|$M^yJarJ;X=I|E&DieT9a7UE58@rw_;mfG%mg3n4+>X7G zDINV8W$>{wd4UPs8tHyn<_K%Vx4t-F{HB0#CbHyT8aIH=*w&T4zhI%?@Yvw4$UHw9 zfiH|AwZ;Wt3m(R<9MXfe~y?7+&yyx)=z7N}~%m5B!YmPaWaH#7@Q+5E; zIqP##(=Vn1;7AlEd2}e2K@tF-TcIq?su`V~Rw@AYX?JP!=ya5wR`qE`V>4fQR+^F$GWKC7sT4IxUFgD9>&BxJs0#D$E0dq8B&$(De03B_O{zBGgT!>|}k{a55 z!O~xj?u?9>EHL(EoJ!?lWDg$AX}pf&%~Sx?@v3~6qvvqAx*Saezy`dwo-+WR!8JMF zpTip|0k{c|kLwhu)oQ!f;y+34?@=W6(zkfKXdO_i)poDN4CtH&58$o=8{em4rdmY+ zbb?>20J>f0o#8w;#fEn(4AdV*y+C*HYaPJI-C#EObp@bT@IwJeLH&YX7XStYpFDt- zf=?R2Fu^AaVA$Z31du2AoO(cqH+@Lz(5e*i5O+3-*HCUO7(002ov JPDHLkV1h8vxv&5L diff --git a/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__list_activated_holo.9.png b/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__list_activated_holo.9.png deleted file mode 100644 index eda10e6123e1e1383c4617228ec0c96680d60dc7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 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?hQAxvX30u5yFboFyt=akR{ E00Z(eO#lD@ diff --git a/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__list_longpressed_holo.9.png b/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__list_longpressed_holo.9.png deleted file mode 100644 index eda10e6123e1e1383c4617228ec0c96680d60dc7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 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 diff --git a/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__list_pressed_holo_light.9.png b/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__list_pressed_holo_light.9.png deleted file mode 100644 index e4b33935a3aa4f1af3fa9e9e199b5c47d43f4b74..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 163 zcmeAS@N?(olHy`uVBq!ia0vp^d?3uh1|;P@bT0xamSQK*5Dp-y;YjHK@;M7UB8wRq zxI00Z(fs7;wLn2vPZ!4!jfu$y_kK-b diff --git a/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__list_selector_disabled_holo_dark.9.png b/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__list_selector_disabled_holo_dark.9.png deleted file mode 100644 index 88726b69160589c8545759440e8d4e69dc984c67..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 190 zcmeAS@N?(olHy`uVBq!ia0vp^azGr$!3HF6SgS1tQk(@Ik;M!Q+?^oIXnykaTA*No zr;B4qM&sKXhJ1$tcw7#es=J@sd2yMiyW@jyg@u(=2qh%>1r1WJE1Ls*cJ{|veUO|(2?8OR-p?Vt(<)KXNk*dJ1<_`!jRpab6RMK;Rk47fDU#NEX#7yk4(~&Fr}L7DZp)K} zK)DDZgb+dqA%qY@2q7)3S*px^wsY!a9l?~jW2$HoDfOAoDc4?$q=mJH$Q@HesW|pH zEqI5t5pt#=^`ykNb$bDA+g_!6r>E#0Ebxb)V~E)@66{HSu%o+0#^7QK=<56_<*0g z4?VWXMFRkJB8s~XX6q}?LEeWW=Ef--P!X+fp` zQ#hbt=1@CWv@?Vrj0n$wG-wfB>s2&!$QdDJ0ulZgw-cuRiR{Y>^Hj3K6cvDZyr8vA z8lxp5*y$r9!v6G_XAF7`2PhmT)XW;J_(x39;8bKfgMu`e! zU+jWXwIOOF0-q>8C*JQsY~7_bBCuA z|Ap1-2&vJi9g(t&*dI@qVtrbEm_q)8uxlUymW^N&DQrSTF2REQdw9B(B*Fk-L?96w zfdFVX0=tCgq*<4>5rKwy4p!?>V+1b~mqyqhPm^M8N}pNlWK7Aa(;L|rtB1{dT%;u; z=)dm(?jeLfE6zhUB!2hW01y9MdY)1v=ujhBx3b+Xm&>Pd9KV)clx)K|j$bdA%O^}( zPFj=H`w_B~E-2}`eIdjBd_I2}hT(GvVW{|jkQIawhG7^!pU>wnc#H_%SRreOrJP6k z#f!~#`~_1^!^gPqw^)9R`+vop3DslHn(o!PiI0dTt@|45Za=)m1`%IwEW{fV$LVaF zE9RVsAMaWMjZlg;f(R_4iy{7r`=s=`3SdP<&^M)TPHqgUw5?z25;3$902*NlyMU*S zpa+j$RH$BIEX`7~H`b|A%pl=Pj|o!QHv-L&MvImjnCmfv9y@5Gq|A_|G$L4MNvqdg zg%(@J38}FG4N!(%uhEggMhM*%9HY#I^l zO-Wr$p$z~$ref=30GgqO)XJdORd}!BEq>NeB8p9{v^kJo2|NxCQwf^HCpGf6X;Wp4 zg!hgmb$FtdtQ>ASMriqL^@|$FBEhNWjw@zMktp~+Gzo9nO1w>OhBUKE#}ER(1L)vD UI+1b(O8@`>07*qoM6N<$f~tseq5uE@ diff --git a/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__menu_dropdown_panel_holo_light.9.png b/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__menu_dropdown_panel_holo_light.9.png deleted file mode 100644 index 93066c8403ddaac9b19571152ef499620bcc0e02..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1551 zcmV+q2JrcbP)ZMyJc+a5x+ehm5NR9U3;9%`Hyz-(tJnPJWK72_ZxFO$7HJ!wl=MA(TM` z5z;&LLlB#EA&f^$3`&>pe6X)LdJ&`vfROKm-xd+jMbSqLMZ|438|}{L$EEgM9M^%w zHa{i`W4qmEM~t#0eOdu-0W1NOh@<%YUknyuBI#0I?3#!O*zRI&T@|+kOaOda%IhNv zM;99T5trXGZJ+ZJPec%b)$c$hhFbzf1btKUoQ@WxJHBtqt%Djjh@==IkkXLZmr_R= zETUs(|D2YHL30h7B}jQ1@s(0WN*y++$>%9Px0_7;Q^61da}ymGVa5oGC6I`(Se|An zXj@SBzbdSFK)Um(Fw#d8Mr2~>phE(63xW_TA*G~C`G7107k~`S4FDISDe;mJcscGO zI_^QW2+SjBmZ1U=9v>gytZ(L+77q^(-%!w_2qCD0PZix`L1IaO$h(b>d0@F@G3Eaa zi55W^GL}q#AgNiNjxa=>FZdR(r+ zxE>NCSff^sd0^fBMHn)m#E-cU=7+{dF-K!9f{S1|kOWYSoDj6e26s~&lfViRc^MJj z^>Y9iF9eSfmVwbcxJ7UPa3MH8F;)otZ%)TN7|p{_AvpQV#UO5SLMWM?>!O$+C0vaD z8(N!X1GsBg3ar^sKmkXku0dO*!9}nfXnYiL)Hg=pYKs73(^zvc9aG}t;{#B5>C;Y2 z2$?l`wfXukgc)%>9s%7AsDyH^rRNDOAHyeHMgYzG`@1jfJOi4h!RzZQK)65|cOA0& z28%R3H(uBEzOL&YU%_z=>~=fscDp^gsmfTk*1@j+TejVzGC zpG{n`bp4r^(iKT*Io^&x%OHc_WZd_EkhCG`k)*sFZ|A&V23>!#)HToxrIRJ-1q1Q~ z3qHxB_z~+bgihSWK3otqlC9O%9BoMC(eAot5j0oOB3|pwbjUE4*ONZd@_Kxq z*B8(0XhE_FfV`ZZwcn~gXn8&5;sQ&h03_lPHzc@QD2L`A0DB!p$qE$r97Hn6cmgfM z$;^GEI@&qEx+o;VEJ0ZAK#dKOL6F|xU|IwgE6|`&x_D{{k^myy5)6fQcS{yR>LIlD zb0eL(UISu`k;Dp-=L_3_9uII4xG36?ZZ5uUxd1Up2yq&z=dNHjN&oIh<{D_CLJUbUG4w?002ovPDHLkV1n`$ Bwt@fv diff --git a/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__progress_bg_holo_dark.9.png b/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__progress_bg_holo_dark.9.png deleted file mode 100644 index 345f5d3067c1b5a2b13f7234238468e8083e75e8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 174 zcmeAS@N?(olHy`uVBq!ia0vp^Ahr?*8<0#p>+uXou@pObhHwBu4M$1`kk47*5n0T@ zz}*SLjOHg#uLTMQc)B=-SoFS~;>gutz{8S$H2ll||1$b2>+ab^8r zChoU9-sVBr1cr+EHAcpdxgPN?*fw!WN@w!F_di=AUe22-xp-2_jNr43yl#?i1$i|o QK(iS+uXou@pObhHwBu4M$1`kk47*5n0T@ zz}*SLjOHg#uLTPFdAc};SoFS~;>gutz{8S$^!?BO&wHlFT~V_1=)TZ8!I{mdT_A)Z zztl5%UbEjFE&+!7%~#Kq{9)d)y{;#I@4EEH*bSem)2!T7Pp)1*OL*gdvC7^*b6)~Y OX7F_Nb6Mw<&;$Uil{z^9 diff --git a/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__progress_primary_holo_dark.9.png b/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__progress_primary_holo_dark.9.png deleted file mode 100644 index c6c3f1ec248835c16ee8a8f9d253769ea4196468..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1309 zcmV+&1>*XNP)>2T29Hys?P&Vm zZA9*OOSNlf`Pu!y*8AUEO|D+e=9Pi3BR)agfw#}SukU>S5_JQH{fFX7qt#y26-7>F z^lg#%AL~){ay($Vl%dNK|ns=8F95J5u4IuT)_iO}FO5AO!x2YA-ev{((MiCMb95Z27y1N{d~<$0ZOiAzT-4$^Y~d8=D&GctVLiOE-HZCX=>916 zaB}eD93BUF6!cN|FY@&i`W7!}IIL?H*U-;b(9ZeC>T4fo-D~%;%Al$SM;o1{CK^c@ zLsL?U%;F5uW`mKV6p@jG8Wm~81rvcAg~E0r38^#=q@={j6{7*N{-mRal zZyi757l1u@+(UUVUpKQfbx4*^AEZ`NBGTk&djR!;W=;+8vR!2ZvkZUiF_Uw;@^@UHY_tFNo|bZ|HqK}~Z_0kB z>1@!nFOf~^{KOi&lvG5Os4i`3m5LaZ>S{(}C2cS_3u25qx+GSC0x^F*mC<6C%zjX} z`(@Gi@=yT|C0D;bu>bAn+W30Hh5ZfH4VVpRc=$wP71`a_ciV~TTQkNXRQHQat7toU zZx*3Z?Q~QYQO|ZUR_Tl#qXtzIiPWWo(#}&aV(i6KuEST$lYVRUVscgaEz?@VCh+@z zYdAdahv=OS&fP(?9$16?`l0%F3gfnP`B71?hw4@2e4pjZouU=>X|R*`N-YD-DJj}uU$#5 zV>X}RzD~bXHhFf?KK=4JTCWrMiS*`U`G2n9l*Y@cp7B$uQwuKJNIF$*XNP)>2T29Hys?P&Vm zZA9*OOSNlf`Pu!y*8AUEO|D+e=9Pi3BR)agfw#}SukU>S5_JQH{fFX7qt#y26-7>F z^lg#%AL~){ay($Vl%dNK|ns=8F95J5u4IuT)_iO}FO5AO!x2YA-ev{((MiCMb95Z27y1N{d~<$0ZOiAzT-4$^Y~d8=D&GctVLiOE-HZCX=>916 zaB}eD93BUF6!cN|FY@&i`W7!}IIL?H*U-;b(9ZeC>T4fo-D~%;%Al$SM;o1{CK^c@ zLsL?U%;F5uW`mKV6p@jG8Wm~81rvcAg~E0r38^#=q@={j6{7*N{-mRal zZyi757l1u@+(UUVUpKQfbx4*^AEZ`NBGTk&djR!;W=;+8vR!2ZvkZUiF_Uw;@^@UHY_tFNo|bZ|HqK}~Z_0kB z>1@!nFOf~^{KOi&lvG5Os4i`3m5LaZ>S{(}C2cS_3u25qx+GSC0x^F*mC<6C%zjX} z`(@Gi@=yT|C0D;bu>bAn+W30Hh5ZfH4VVpRc=$wP71`a_ciV~TTQkNXRQHQat7toU zZx*3Z?Q~QYQO|ZUR_Tl#qXtzIiPWWo(#}&aV(i6KuEST$lYVRUVscgaEz?@VCh+@z zYdAdahv=OS&fP(?9$16?`l0%F3gfnP`B71?hw4@2e4pjZouU=>X|R*`N-YD-DJj}uU$#5 zV>X}RzD~bXHhFf?KK=4JTCWrMiS*`U`G2n9l*Y@cp7B$uQwuKJNIF$+uXou@pObhHwBu4M$1`kk47*5n0T@ zz}*SLjOHg#uLTN5dAc};So9|U`2XLYnVI=;y-5$#f-D2o4GsT&Tr`prfMCHsr=)`p zy9zZlQWAk&gL|Kjh|gcN+0MxMkn!S`=@A+#%ic(Om>d23|9^ht#EF9It^fc3f1ZP3 Y!dJ=4-o~HPfwnMsy85}Sb4q9e06h#o+yDRo diff --git a/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__progress_secondary_holo_light.9.png b/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__progress_secondary_holo_light.9.png deleted file mode 100644 index 205b66e2cdef686c5ed6369b14e64b38d0182984..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 184 zcmeAS@N?(olHy`uVBq!ia0vp^Ahr?*8<0#p>+uXou@pObhHwBu4M$1`kk47*5n0T@ zz}*SLjOHg#uLTN5dAc};So9|U`2XLYnVI=;y-5$#f-D2o4GsT&Tr`prfMCHsr=)`p zy9zZlQWAk&gL|Kjh|gcN+0MxMkn!S`=@A+#%ic(Om>d23|9^ht#EF9It^fc3f1ZP3 Y!dJ=4-o~HPfwnMsy85}Sb4q9e06h#o+yDRo diff --git a/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__spinner_48_inner_holo.png b/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__spinner_48_inner_holo.png deleted file mode 100644 index 19517c4b0aee1010c7041a76089fdfdbfa495e80..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2769 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 diff --git a/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__spinner_ab_default_holo_dark.9.png b/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__spinner_ab_default_holo_dark.9.png deleted file mode 100644 index d8929fcd1864e92c78f24d34bb07ac0304bf5ebe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 395 zcmV;60d)R}P)%)khMb;v@5Yo)-?A$vWI3J{&4Tqm)VM&;#i3-!rXQ;}}A|kSK_xLoQ9!D=| zrQuRX_jo!D&!*woG(4MzXVdU(8lG)+!_Dl;%pOYTRyEwrUVwMtwRCnh!_9059DxJy zTsprAUsT~zdJlX8e>K+(FMd_}2<&RF8#?@^bn(8vHtbfpl-_eLJ!>=!D!!z&OE12( zv`a1CqqIva-mA1rDc-ZR3oqWgvUXO(tc zif5K~i;HKMc8iLSDD9eyk1Fk&iksP%L8V=5@ekmQ^NVfO%k2z5z^Qbob@&(X-FR)u p3HS~A?&0(Ut%!)oJooy?_kZokYAURbJh}h?002ovPDHLkV1n7-uz&yn diff --git a/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__spinner_ab_default_holo_light.9.png b/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__spinner_ab_default_holo_light.9.png deleted file mode 100644 index 9174c4e4bc984a89e1ed643bc66b1569466ef52b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 394 zcmV;50d@X~P)pS_@$ zhD#gW|+S$zvH?tjZ06u}I z+WCj@MGelS_rM46*K*DD;uob4z^?VWsl%^ISMTdf({7b>={={?i$=qw;%iE~^x|tv zyVT+%O1re;qe{D!;v-AD@ZzIOyU^khrCnI@sM0Q^cw}ieym)kJH?(+0X*aBRR%th+ zcxGw0x_EYJx2pJz(yqJstkSNlxS72&skG}Y{tg(Y7u%+n+Xa4rW9?Ay@Gs!I^V*st o@Ei2q)9D9V5fPDPZuO7v|4Ms3SH1lZVgLXD07*qoM6N<$f(F>P&Hw-a diff --git a/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__spinner_ab_disabled_holo_dark.9.png b/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__spinner_ab_disabled_holo_dark.9.png deleted file mode 100644 index 3015d307088f12d52a9e99ff4575fd2153127e5b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 381 zcmV-@0fPRCP)hG*08Y#N?T!?S64w!;lKvy+*1?>p3RGdlx#190x$dzj&7b^-9QUftoB@I?dG z(l;!l|3;oEFaA*ajtwD8hd-6>9*;+5M`bO2!%}+FXrQS0p3;u)|QJUO}XO$+G;+dssck%4fw5xbU zX__uxRhp)XSC*#P;_m>iSbo@k`^^CW{9xcU{p|2h0AG{O_A~&$L7!btFK9(XM7DX= bKfeD1Etg?&Fp}qT00000NkvXXu0mjfW#pxI diff --git a/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__spinner_ab_disabled_holo_light.9.png b/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__spinner_ab_disabled_holo_light.9.png deleted file mode 100644 index 126637d1194f1d6609787774fb140818eaa4ba1f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 381 zcmV-@0fPRCP)hG*08Y#N?T!?S64w!;lKvy+*1?>p3RGdlx#190x$dzj&7b^-9QUftoB@I?dG z(l;!l|3;oEFaA*ajtwD8hd-6>9*;+5M`bO2!%}+FXrQS0p3;u)|QJUO}XO$+G;+dssck%4fw5xbU zX__uxRhp)XSC*#P;_m>iSbo@k`^^CW{9xcU{p|2h0AG{O_A~&$L7!btFK9(XM7DX= bKfeD1iaRu(IeFS@00000NkvXXu0mjfR7Ip< diff --git a/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__spinner_ab_focused_holo_dark.9.png b/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__spinner_ab_focused_holo_dark.9.png deleted file mode 100644 index d45c7a864d9b36fc5d06ef7650bd22c228e3533e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 680 zcmV;Z0$2TsP)JMg@Fn128fNR{httc z2n-9ae~A~-WYQOAyjJ3`v+tFS>H?h>cjZI44!YCDJ4vU-UH-NFC!H?dNqTY9^x~%J z#ZA+To2C~xO)qX5=ft;__PrJUYC9#q>!rbyQFMFHPb=3hoe|&n)9~p|baWUbMthlMtLL6k^E5&wx9H zfkWKo4DxGy27JSv%4KLW#~I|sPnXY+fCHfNj(}ks%-+uyBgtHbMG(R)| O00009q_DOpcx|jv*P1Z)f>u3p>g<+)ulGcHZsoOUd0`v$ideb3Xs*rv6J! zg}R0?Ejbavstni13%M+(h~#=Y?=G{+sY|c-R?LyC;M~J_EGz53I-4BR z+cU4@A4T%4{LQ{7{nooe_R?;9Ufq56+wp;!Z_W|LdHU^V zuiix!E)rt*mg%eid+||lw)K3kxzR2XQeoHKTo0e>Tz_Z7KF;I+KDl^G6{a%9AKj}v z@Aq1v55LRoZXbD)<16^lF!*Li$^7}+)mu{zFEMCaSs}k;w&aatvA+!FKCV6>P_Fen z(L?roLe!sxPkWei7+T9&rtD<0W7^%ZdcE}hdZyQpKhHVIBAEwFVGN$GelF{r5}E)^ Cjyh@p diff --git a/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__spinner_ab_pressed_holo_dark.9.png b/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__spinner_ab_pressed_holo_dark.9.png deleted file mode 100644 index 2cb34d7f60401a563454c03e266cc5181d9de996..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 609 zcmV-n0-pVeP)%5ec8;(Nh#y0Zthco9&fD+Scz(J_kqCSd>@N)Jrb#iJx@ z@geV)|0U|;Q8J4AW)%0$DDIn4+&81RZ$@$73{E^#CTa6Odr;zqGLyGk)zfLB)26Y5 z5#LU9dOW?JALQjc$4r{WH?GVFg))<)qMW_Ts@W~*Hgkd(m(u%LwVNxGwVfAK{BG$~ zHD4Zg33jP$CptYU%GrKa?RJ%hK*cvHEqE`!X=%Z0aT}!tZ^dnu7Q7Uk{&1!u)wl@^>7cUfAnUfgwQ!D?|Ir3GuneU%oh6!%$L*todw(!xf?LzEVJ7Y|ih z=v92GOd6`R(5v{nqI~u|T|T)5eQi`_Q>fI*QllCl)AthpQf>YCTIE0c%xyxW%x|6C zG>z*e{-?!>T@(EFL|;a6&!||%qb(l4cp2298zt1@mjOk(atXEgIq-{NzY%9xIi5qk vb6%{!-vcjz*7vDBaRYn@J|M2KzWDwRiVUw(_ikNA00000NkvXXu0mjfOP&sp diff --git a/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__spinner_ab_pressed_holo_light.9.png b/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__spinner_ab_pressed_holo_light.9.png deleted file mode 100644 index 82f752fdc28390f1dae188e66886f9fee783b4f7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 602 zcmV-g0;TXoV&|>P?2N3a|H=XkIpb%g2C{mUcD8z%K5!WW71`A3B@}P?c zNzmeTUM-&`=;A@rh-=e`Ytx8p(}-)+h-=e`Yg0e*Nfwct-zMuNo?gfN+FNCOm6(Rs zNBrh8;rK_F^Mfu~8k>e2?@WdCI_7lHVR+IZj_>A~;=j0*zBpPVOJB@8&9C^w(v!^i zcs#`4qjGbZa60I4akN%e8hjOBptPW0e8JL!ZgC5x1-;^yN((y0EtVGC7q?tma9i9# zX~A7_N2LWf#T}Lw>=$=jTCiJOp|oJHxKe4sPI1N3!s5l1OACt?_fT4>Uffe@p<40r zRpP6(P_6jSy?2bx-x9}n#O>6o(Q^BiC^BxWR1^RB?JvEr|0>Nj5k)!eSD9&8HSzXK z2sbij-vth4?P;pL%~0mos(Tg<|DAn;kcS obzts&Y9%t@53qx{hWg?AJqc6disFjI`v3p{07*qoM6N<$f`4nJ zaCd?*qxs3xYk`8Mo-U3d5>t~6?){q5*x2~c-pCBZ5@_=ERFyG diff --git a/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__tab_selected_holo.9.png b/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__tab_selected_holo.9.png deleted file mode 100644 index e4229f26b2771d884934b80d0056b8dd66d10edd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 153 zcmeAS@N?(olHy`uVBq!ia0vp^Y(Ol;0U|59*B=E^EX7WqAsj$Z!;#Vf4nJ zaCd?*qxs3xYk`8+o-U3d5>t~6?){q5*x2~c-l(n1@K5>ymj5$1a2Oc?!34d7Ck`Aq skg(^gW|wXH-lZoEvTk@AJm}J3sQWAGentL}KF}BjPgg&ebxsLQ0KFYBT>t<8 diff --git a/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__tab_selected_pressed_holo.9.png b/android-libraries/ActionBarSherlock/res/drawable-xhdpi/abs__tab_selected_pressed_holo.9.png deleted file mode 100644 index e862cb12154541c150fb2d9bb98872bcff506317..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 147 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 diff --git a/android-libraries/ActionBarSherlock/res/drawable/abs__activated_background_holo_dark.xml b/android-libraries/ActionBarSherlock/res/drawable/abs__activated_background_holo_dark.xml deleted file mode 100644 index 85c2c0212..000000000 --- a/android-libraries/ActionBarSherlock/res/drawable/abs__activated_background_holo_dark.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - diff --git a/android-libraries/ActionBarSherlock/res/drawable/abs__activated_background_holo_light.xml b/android-libraries/ActionBarSherlock/res/drawable/abs__activated_background_holo_light.xml deleted file mode 100644 index 85c2c0212..000000000 --- a/android-libraries/ActionBarSherlock/res/drawable/abs__activated_background_holo_light.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - diff --git a/android-libraries/ActionBarSherlock/res/drawable/abs__btn_cab_done_holo_dark.xml b/android-libraries/ActionBarSherlock/res/drawable/abs__btn_cab_done_holo_dark.xml deleted file mode 100644 index cab896283..000000000 --- a/android-libraries/ActionBarSherlock/res/drawable/abs__btn_cab_done_holo_dark.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - diff --git a/android-libraries/ActionBarSherlock/res/drawable/abs__btn_cab_done_holo_light.xml b/android-libraries/ActionBarSherlock/res/drawable/abs__btn_cab_done_holo_light.xml deleted file mode 100644 index 42ba8a0df..000000000 --- a/android-libraries/ActionBarSherlock/res/drawable/abs__btn_cab_done_holo_light.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - diff --git a/android-libraries/ActionBarSherlock/res/drawable/abs__ic_menu_moreoverflow_holo_dark.xml b/android-libraries/ActionBarSherlock/res/drawable/abs__ic_menu_moreoverflow_holo_dark.xml deleted file mode 100644 index 2588a492d..000000000 --- a/android-libraries/ActionBarSherlock/res/drawable/abs__ic_menu_moreoverflow_holo_dark.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - diff --git a/android-libraries/ActionBarSherlock/res/drawable/abs__ic_menu_moreoverflow_holo_light.xml b/android-libraries/ActionBarSherlock/res/drawable/abs__ic_menu_moreoverflow_holo_light.xml deleted file mode 100644 index e2078c967..000000000 --- a/android-libraries/ActionBarSherlock/res/drawable/abs__ic_menu_moreoverflow_holo_light.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - diff --git a/android-libraries/ActionBarSherlock/res/drawable/abs__item_background_holo_dark.xml b/android-libraries/ActionBarSherlock/res/drawable/abs__item_background_holo_dark.xml deleted file mode 100644 index d99b7a426..000000000 --- a/android-libraries/ActionBarSherlock/res/drawable/abs__item_background_holo_dark.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - diff --git a/android-libraries/ActionBarSherlock/res/drawable/abs__item_background_holo_light.xml b/android-libraries/ActionBarSherlock/res/drawable/abs__item_background_holo_light.xml deleted file mode 100644 index da5fb2e86..000000000 --- a/android-libraries/ActionBarSherlock/res/drawable/abs__item_background_holo_light.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - diff --git a/android-libraries/ActionBarSherlock/res/drawable/abs__list_selector_background_transition_holo_dark.xml b/android-libraries/ActionBarSherlock/res/drawable/abs__list_selector_background_transition_holo_dark.xml deleted file mode 100644 index b2ce4f0f7..000000000 --- a/android-libraries/ActionBarSherlock/res/drawable/abs__list_selector_background_transition_holo_dark.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - diff --git a/android-libraries/ActionBarSherlock/res/drawable/abs__list_selector_background_transition_holo_light.xml b/android-libraries/ActionBarSherlock/res/drawable/abs__list_selector_background_transition_holo_light.xml deleted file mode 100644 index d7e31b1d1..000000000 --- a/android-libraries/ActionBarSherlock/res/drawable/abs__list_selector_background_transition_holo_light.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - diff --git a/android-libraries/ActionBarSherlock/res/drawable/abs__list_selector_holo_dark.xml b/android-libraries/ActionBarSherlock/res/drawable/abs__list_selector_holo_dark.xml deleted file mode 100644 index 08b8b12f3..000000000 --- a/android-libraries/ActionBarSherlock/res/drawable/abs__list_selector_holo_dark.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - diff --git a/android-libraries/ActionBarSherlock/res/drawable/abs__list_selector_holo_light.xml b/android-libraries/ActionBarSherlock/res/drawable/abs__list_selector_holo_light.xml deleted file mode 100644 index ada490bf9..000000000 --- a/android-libraries/ActionBarSherlock/res/drawable/abs__list_selector_holo_light.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/android-libraries/ActionBarSherlock/res/drawable/abs__progress_horizontal_holo_dark.xml b/android-libraries/ActionBarSherlock/res/drawable/abs__progress_horizontal_holo_dark.xml deleted file mode 100644 index bd19140ab..000000000 --- a/android-libraries/ActionBarSherlock/res/drawable/abs__progress_horizontal_holo_dark.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/android-libraries/ActionBarSherlock/res/drawable/abs__progress_horizontal_holo_light.xml b/android-libraries/ActionBarSherlock/res/drawable/abs__progress_horizontal_holo_light.xml deleted file mode 100644 index 321f07c8b..000000000 --- a/android-libraries/ActionBarSherlock/res/drawable/abs__progress_horizontal_holo_light.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/android-libraries/ActionBarSherlock/res/drawable/abs__progress_medium_holo.xml b/android-libraries/ActionBarSherlock/res/drawable/abs__progress_medium_holo.xml deleted file mode 100644 index 6d4814f86..000000000 --- a/android-libraries/ActionBarSherlock/res/drawable/abs__progress_medium_holo.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - diff --git a/android-libraries/ActionBarSherlock/res/drawable/abs__spinner_ab_holo_dark.xml b/android-libraries/ActionBarSherlock/res/drawable/abs__spinner_ab_holo_dark.xml deleted file mode 100644 index 4af5e22a9..000000000 --- a/android-libraries/ActionBarSherlock/res/drawable/abs__spinner_ab_holo_dark.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - diff --git a/android-libraries/ActionBarSherlock/res/drawable/abs__spinner_ab_holo_light.xml b/android-libraries/ActionBarSherlock/res/drawable/abs__spinner_ab_holo_light.xml deleted file mode 100644 index b78508478..000000000 --- a/android-libraries/ActionBarSherlock/res/drawable/abs__spinner_ab_holo_light.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - diff --git a/android-libraries/ActionBarSherlock/res/drawable/abs__tab_indicator_ab_holo.xml b/android-libraries/ActionBarSherlock/res/drawable/abs__tab_indicator_ab_holo.xml deleted file mode 100644 index d34e20811..000000000 --- a/android-libraries/ActionBarSherlock/res/drawable/abs__tab_indicator_ab_holo.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/android-libraries/ActionBarSherlock/res/layout-large/abs__action_mode_close_item.xml b/android-libraries/ActionBarSherlock/res/layout-large/abs__action_mode_close_item.xml deleted file mode 100644 index 8811dad8d..000000000 --- a/android-libraries/ActionBarSherlock/res/layout-large/abs__action_mode_close_item.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - diff --git a/android-libraries/ActionBarSherlock/res/layout-v14/sherlock_spinner_dropdown_item.xml b/android-libraries/ActionBarSherlock/res/layout-v14/sherlock_spinner_dropdown_item.xml deleted file mode 100644 index 6c183c059..000000000 --- a/android-libraries/ActionBarSherlock/res/layout-v14/sherlock_spinner_dropdown_item.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - diff --git a/android-libraries/ActionBarSherlock/res/layout-v14/sherlock_spinner_item.xml b/android-libraries/ActionBarSherlock/res/layout-v14/sherlock_spinner_item.xml deleted file mode 100644 index 61dc02527..000000000 --- a/android-libraries/ActionBarSherlock/res/layout-v14/sherlock_spinner_item.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - diff --git a/android-libraries/ActionBarSherlock/res/layout-xlarge/abs__screen_action_bar.xml b/android-libraries/ActionBarSherlock/res/layout-xlarge/abs__screen_action_bar.xml deleted file mode 100644 index 040df44ab..000000000 --- a/android-libraries/ActionBarSherlock/res/layout-xlarge/abs__screen_action_bar.xml +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - - - - - - diff --git a/android-libraries/ActionBarSherlock/res/layout-xlarge/abs__screen_action_bar_overlay.xml b/android-libraries/ActionBarSherlock/res/layout-xlarge/abs__screen_action_bar_overlay.xml deleted file mode 100644 index c64ef141b..000000000 --- a/android-libraries/ActionBarSherlock/res/layout-xlarge/abs__screen_action_bar_overlay.xml +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - - - - - - diff --git a/android-libraries/ActionBarSherlock/res/layout/abs__action_bar_home.xml b/android-libraries/ActionBarSherlock/res/layout/abs__action_bar_home.xml deleted file mode 100644 index 5c1e9ec4b..000000000 --- a/android-libraries/ActionBarSherlock/res/layout/abs__action_bar_home.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - diff --git a/android-libraries/ActionBarSherlock/res/layout/abs__action_bar_tab.xml b/android-libraries/ActionBarSherlock/res/layout/abs__action_bar_tab.xml deleted file mode 100644 index f46f7a044..000000000 --- a/android-libraries/ActionBarSherlock/res/layout/abs__action_bar_tab.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - \ No newline at end of file diff --git a/android-libraries/ActionBarSherlock/res/layout/abs__action_bar_tab_bar_view.xml b/android-libraries/ActionBarSherlock/res/layout/abs__action_bar_tab_bar_view.xml deleted file mode 100644 index 0d51220c9..000000000 --- a/android-libraries/ActionBarSherlock/res/layout/abs__action_bar_tab_bar_view.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - \ No newline at end of file diff --git a/android-libraries/ActionBarSherlock/res/layout/abs__action_bar_title_item.xml b/android-libraries/ActionBarSherlock/res/layout/abs__action_bar_title_item.xml deleted file mode 100644 index dd69acada..000000000 --- a/android-libraries/ActionBarSherlock/res/layout/abs__action_bar_title_item.xml +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - - - - - - diff --git a/android-libraries/ActionBarSherlock/res/layout/abs__action_menu_item_layout.xml b/android-libraries/ActionBarSherlock/res/layout/abs__action_menu_item_layout.xml deleted file mode 100644 index 13149fd63..000000000 --- a/android-libraries/ActionBarSherlock/res/layout/abs__action_menu_item_layout.xml +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - diff --git a/android-libraries/ActionBarSherlock/res/layout/abs__action_menu_layout.xml b/android-libraries/ActionBarSherlock/res/layout/abs__action_menu_layout.xml deleted file mode 100644 index a6f8e53f8..000000000 --- a/android-libraries/ActionBarSherlock/res/layout/abs__action_menu_layout.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - diff --git a/android-libraries/ActionBarSherlock/res/layout/abs__action_mode_bar.xml b/android-libraries/ActionBarSherlock/res/layout/abs__action_mode_bar.xml deleted file mode 100644 index 7168dc77f..000000000 --- a/android-libraries/ActionBarSherlock/res/layout/abs__action_mode_bar.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - diff --git a/android-libraries/ActionBarSherlock/res/layout/abs__action_mode_close_item.xml b/android-libraries/ActionBarSherlock/res/layout/abs__action_mode_close_item.xml deleted file mode 100644 index 875ec3e1b..000000000 --- a/android-libraries/ActionBarSherlock/res/layout/abs__action_mode_close_item.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - diff --git a/android-libraries/ActionBarSherlock/res/layout/abs__activity_chooser_view.xml b/android-libraries/ActionBarSherlock/res/layout/abs__activity_chooser_view.xml deleted file mode 100644 index 019d14ef4..000000000 --- a/android-libraries/ActionBarSherlock/res/layout/abs__activity_chooser_view.xml +++ /dev/null @@ -1,70 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/android-libraries/ActionBarSherlock/res/layout/abs__activity_chooser_view_list_item.xml b/android-libraries/ActionBarSherlock/res/layout/abs__activity_chooser_view_list_item.xml deleted file mode 100644 index b430032a1..000000000 --- a/android-libraries/ActionBarSherlock/res/layout/abs__activity_chooser_view_list_item.xml +++ /dev/null @@ -1,53 +0,0 @@ - - - - - - - - - - - - - - diff --git a/android-libraries/ActionBarSherlock/res/layout/abs__dialog_title_holo.xml b/android-libraries/ActionBarSherlock/res/layout/abs__dialog_title_holo.xml deleted file mode 100644 index 6402f28be..000000000 --- a/android-libraries/ActionBarSherlock/res/layout/abs__dialog_title_holo.xml +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - - - - diff --git a/android-libraries/ActionBarSherlock/res/layout/abs__list_menu_item_checkbox.xml b/android-libraries/ActionBarSherlock/res/layout/abs__list_menu_item_checkbox.xml deleted file mode 100644 index 39aca3a8d..000000000 --- a/android-libraries/ActionBarSherlock/res/layout/abs__list_menu_item_checkbox.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - diff --git a/android-libraries/ActionBarSherlock/res/layout/abs__list_menu_item_icon.xml b/android-libraries/ActionBarSherlock/res/layout/abs__list_menu_item_icon.xml deleted file mode 100644 index 55ab28a24..000000000 --- a/android-libraries/ActionBarSherlock/res/layout/abs__list_menu_item_icon.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - diff --git a/android-libraries/ActionBarSherlock/res/layout/abs__list_menu_item_layout.xml b/android-libraries/ActionBarSherlock/res/layout/abs__list_menu_item_layout.xml deleted file mode 100644 index 147f36fe8..000000000 --- a/android-libraries/ActionBarSherlock/res/layout/abs__list_menu_item_layout.xml +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/android-libraries/ActionBarSherlock/res/layout/abs__list_menu_item_radio.xml b/android-libraries/ActionBarSherlock/res/layout/abs__list_menu_item_radio.xml deleted file mode 100644 index ff54bbecd..000000000 --- a/android-libraries/ActionBarSherlock/res/layout/abs__list_menu_item_radio.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - diff --git a/android-libraries/ActionBarSherlock/res/layout/abs__popup_menu_item_layout.xml b/android-libraries/ActionBarSherlock/res/layout/abs__popup_menu_item_layout.xml deleted file mode 100644 index d42425ad3..000000000 --- a/android-libraries/ActionBarSherlock/res/layout/abs__popup_menu_item_layout.xml +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/android-libraries/ActionBarSherlock/res/layout/abs__screen_action_bar.xml b/android-libraries/ActionBarSherlock/res/layout/abs__screen_action_bar.xml deleted file mode 100644 index 1fb82fe9a..000000000 --- a/android-libraries/ActionBarSherlock/res/layout/abs__screen_action_bar.xml +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - - - - - - - - diff --git a/android-libraries/ActionBarSherlock/res/layout/abs__screen_action_bar_overlay.xml b/android-libraries/ActionBarSherlock/res/layout/abs__screen_action_bar_overlay.xml deleted file mode 100644 index 0961ef561..000000000 --- a/android-libraries/ActionBarSherlock/res/layout/abs__screen_action_bar_overlay.xml +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - - - - - diff --git a/android-libraries/ActionBarSherlock/res/layout/abs__screen_simple.xml b/android-libraries/ActionBarSherlock/res/layout/abs__screen_simple.xml deleted file mode 100644 index 33e2dea0d..000000000 --- a/android-libraries/ActionBarSherlock/res/layout/abs__screen_simple.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - diff --git a/android-libraries/ActionBarSherlock/res/layout/abs__screen_simple_overlay_action_mode.xml b/android-libraries/ActionBarSherlock/res/layout/abs__screen_simple_overlay_action_mode.xml deleted file mode 100644 index f8b9fb185..000000000 --- a/android-libraries/ActionBarSherlock/res/layout/abs__screen_simple_overlay_action_mode.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - diff --git a/android-libraries/ActionBarSherlock/res/layout/main.xml b/android-libraries/ActionBarSherlock/res/layout/main.xml deleted file mode 100644 index ac9c0abab..000000000 --- a/android-libraries/ActionBarSherlock/res/layout/main.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/android-libraries/ActionBarSherlock/res/layout/sherlock_spinner_dropdown_item.xml b/android-libraries/ActionBarSherlock/res/layout/sherlock_spinner_dropdown_item.xml deleted file mode 100644 index a6c6252d2..000000000 --- a/android-libraries/ActionBarSherlock/res/layout/sherlock_spinner_dropdown_item.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - diff --git a/android-libraries/ActionBarSherlock/res/layout/sherlock_spinner_item.xml b/android-libraries/ActionBarSherlock/res/layout/sherlock_spinner_item.xml deleted file mode 100644 index bea740178..000000000 --- a/android-libraries/ActionBarSherlock/res/layout/sherlock_spinner_item.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - diff --git a/android-libraries/ActionBarSherlock/res/values-land/abs__dimens.xml b/android-libraries/ActionBarSherlock/res/values-land/abs__dimens.xml deleted file mode 100644 index 502cc16a3..000000000 --- a/android-libraries/ActionBarSherlock/res/values-land/abs__dimens.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - 40dip - - 4dip - - 16dp - - 12dp - - -2dp - - 4dip - diff --git a/android-libraries/ActionBarSherlock/res/values-large-hdpi-1024x600/abs__dimens.xml b/android-libraries/ActionBarSherlock/res/values-large-hdpi-1024x600/abs__dimens.xml deleted file mode 100644 index 3312cfa7f..000000000 --- a/android-libraries/ActionBarSherlock/res/values-large-hdpi-1024x600/abs__dimens.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - 48dip - - 8dip - - 18dp - - 14dp - - -3dp - - 5dip - diff --git a/android-libraries/ActionBarSherlock/res/values-large-land-hdpi-1024x600/abs__dimens.xml b/android-libraries/ActionBarSherlock/res/values-large-land-hdpi-1024x600/abs__dimens.xml deleted file mode 100644 index 502cc16a3..000000000 --- a/android-libraries/ActionBarSherlock/res/values-large-land-hdpi-1024x600/abs__dimens.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - 40dip - - 4dip - - 16dp - - 12dp - - -2dp - - 4dip - diff --git a/android-libraries/ActionBarSherlock/res/values-large-land-mdpi-1024x600/abs__dimens.xml b/android-libraries/ActionBarSherlock/res/values-large-land-mdpi-1024x600/abs__dimens.xml deleted file mode 100644 index 3312cfa7f..000000000 --- a/android-libraries/ActionBarSherlock/res/values-large-land-mdpi-1024x600/abs__dimens.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - 48dip - - 8dip - - 18dp - - 14dp - - -3dp - - 5dip - diff --git a/android-libraries/ActionBarSherlock/res/values-large-mdpi-1024x600/abs__dimens.xml b/android-libraries/ActionBarSherlock/res/values-large-mdpi-1024x600/abs__dimens.xml deleted file mode 100644 index 35910333b..000000000 --- a/android-libraries/ActionBarSherlock/res/values-large-mdpi-1024x600/abs__dimens.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - 56dip - - 4dip - - 18dp - - 14dp - - -3dp - - 9dip - - - 64dip - diff --git a/android-libraries/ActionBarSherlock/res/values-large/abs__dimens.xml b/android-libraries/ActionBarSherlock/res/values-large/abs__dimens.xml deleted file mode 100644 index 63b12f7f3..000000000 --- a/android-libraries/ActionBarSherlock/res/values-large/abs__dimens.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - 55% - - 80% - diff --git a/android-libraries/ActionBarSherlock/res/values-sw600dp/abs__bools.xml b/android-libraries/ActionBarSherlock/res/values-sw600dp/abs__bools.xml deleted file mode 100644 index 7a48e1542..000000000 --- a/android-libraries/ActionBarSherlock/res/values-sw600dp/abs__bools.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - false - diff --git a/android-libraries/ActionBarSherlock/res/values-sw600dp/abs__dimens.xml b/android-libraries/ActionBarSherlock/res/values-sw600dp/abs__dimens.xml deleted file mode 100644 index f67853817..000000000 --- a/android-libraries/ActionBarSherlock/res/values-sw600dp/abs__dimens.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - - - 56dip - - 4dip - - 18dp - - 14dp - - -3dp - - 9dip - - 5 - - - 64dip - diff --git a/android-libraries/ActionBarSherlock/res/values-v11/abs__themes.xml b/android-libraries/ActionBarSherlock/res/values-v11/abs__themes.xml deleted file mode 100644 index 03473572c..000000000 --- a/android-libraries/ActionBarSherlock/res/values-v11/abs__themes.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - diff --git a/android-libraries/ActionBarSherlock/res/values-v14/abs__styles.xml b/android-libraries/ActionBarSherlock/res/values-v14/abs__styles.xml deleted file mode 100644 index f2aa64d2d..000000000 --- a/android-libraries/ActionBarSherlock/res/values-v14/abs__styles.xml +++ /dev/null @@ -1,118 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/android-libraries/ActionBarSherlock/res/values-v14/abs__themes.xml b/android-libraries/ActionBarSherlock/res/values-v14/abs__themes.xml deleted file mode 100644 index ceb960737..000000000 --- a/android-libraries/ActionBarSherlock/res/values-v14/abs__themes.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - diff --git a/android-libraries/ActionBarSherlock/res/values-w360dp/abs__dimens.xml b/android-libraries/ActionBarSherlock/res/values-w360dp/abs__dimens.xml deleted file mode 100644 index 6f49d7e47..000000000 --- a/android-libraries/ActionBarSherlock/res/values-w360dp/abs__dimens.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - 3 - diff --git a/android-libraries/ActionBarSherlock/res/values-w480dp/abs__bools.xml b/android-libraries/ActionBarSherlock/res/values-w480dp/abs__bools.xml deleted file mode 100644 index 3eaf4aee9..000000000 --- a/android-libraries/ActionBarSherlock/res/values-w480dp/abs__bools.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - true - false - diff --git a/android-libraries/ActionBarSherlock/res/values-w480dp/abs__config.xml b/android-libraries/ActionBarSherlock/res/values-w480dp/abs__config.xml deleted file mode 100644 index 88357b0a7..000000000 --- a/android-libraries/ActionBarSherlock/res/values-w480dp/abs__config.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - true - - diff --git a/android-libraries/ActionBarSherlock/res/values-w500dp/abs__dimens.xml b/android-libraries/ActionBarSherlock/res/values-w500dp/abs__dimens.xml deleted file mode 100644 index 2fd4deea2..000000000 --- a/android-libraries/ActionBarSherlock/res/values-w500dp/abs__dimens.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - 4 - diff --git a/android-libraries/ActionBarSherlock/res/values-w600dp/abs__dimens.xml b/android-libraries/ActionBarSherlock/res/values-w600dp/abs__dimens.xml deleted file mode 100644 index b085952d3..000000000 --- a/android-libraries/ActionBarSherlock/res/values-w600dp/abs__dimens.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - 5 - diff --git a/android-libraries/ActionBarSherlock/res/values-xlarge/abs__dimens.xml b/android-libraries/ActionBarSherlock/res/values-xlarge/abs__dimens.xml deleted file mode 100644 index bfc535de1..000000000 --- a/android-libraries/ActionBarSherlock/res/values-xlarge/abs__dimens.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - - - 56dip - - 4dip - - 18dp - - 14dp - - -3dp - - 9dip - - - 64dip - - - 45% - - 72% - diff --git a/android-libraries/ActionBarSherlock/res/values/abs__attrs.xml b/android-libraries/ActionBarSherlock/res/values/abs__attrs.xml deleted file mode 100644 index 81c347108..000000000 --- a/android-libraries/ActionBarSherlock/res/values/abs__attrs.xml +++ /dev/null @@ -1,380 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/android-libraries/ActionBarSherlock/res/values/abs__bools.xml b/android-libraries/ActionBarSherlock/res/values/abs__bools.xml deleted file mode 100644 index 0b432448d..000000000 --- a/android-libraries/ActionBarSherlock/res/values/abs__bools.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - false - true - true - - diff --git a/android-libraries/ActionBarSherlock/res/values/abs__colors.xml b/android-libraries/ActionBarSherlock/res/values/abs__colors.xml deleted file mode 100644 index 625c632ff..000000000 --- a/android-libraries/ActionBarSherlock/res/values/abs__colors.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - #ff000000 - #fff3f3f3 - @color/abs__background_holo_light - @color/abs__background_holo_dark - #ff4c4c4c - #ffb2b2b2 - @color/abs__bright_foreground_holo_light - @color/abs__bright_foreground_holo_dark - #ff33b5e5 - diff --git a/android-libraries/ActionBarSherlock/res/values/abs__config.xml b/android-libraries/ActionBarSherlock/res/values/abs__config.xml deleted file mode 100644 index 4c7b5d459..000000000 --- a/android-libraries/ActionBarSherlock/res/values/abs__config.xml +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - 320dp - - - false - - - true - - - false - - diff --git a/android-libraries/ActionBarSherlock/res/values/abs__dimens.xml b/android-libraries/ActionBarSherlock/res/values/abs__dimens.xml deleted file mode 100644 index 0a409756c..000000000 --- a/android-libraries/ActionBarSherlock/res/values/abs__dimens.xml +++ /dev/null @@ -1,50 +0,0 @@ - - - - - 48dip - - 8dip - - 18dp - - 14dp - - -3dp - - 5dip - - 2 - - - 56dip - - - 64dip - - - 65% - - 95% - diff --git a/android-libraries/ActionBarSherlock/res/values/abs__ids.xml b/android-libraries/ActionBarSherlock/res/values/abs__ids.xml deleted file mode 100644 index f9f56045b..000000000 --- a/android-libraries/ActionBarSherlock/res/values/abs__ids.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - diff --git a/android-libraries/ActionBarSherlock/res/values/abs__strings.xml b/android-libraries/ActionBarSherlock/res/values/abs__strings.xml deleted file mode 100644 index 1e1c7022c..000000000 --- a/android-libraries/ActionBarSherlock/res/values/abs__strings.xml +++ /dev/null @@ -1,42 +0,0 @@ - - - - - Navigate home - - Navigate up - - More options - - - Done - - - See all... - - Select activity - - Share with... - - Choose an application - - Share with - - Share with %s - diff --git a/android-libraries/ActionBarSherlock/res/values/abs__styles.xml b/android-libraries/ActionBarSherlock/res/values/abs__styles.xml deleted file mode 100644 index 8cbd36484..000000000 --- a/android-libraries/ActionBarSherlock/res/values/abs__styles.xml +++ /dev/null @@ -1,384 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/android-libraries/ActionBarSherlock/res/values/abs__themes.xml b/android-libraries/ActionBarSherlock/res/values/abs__themes.xml deleted file mode 100644 index 5300dedd6..000000000 --- a/android-libraries/ActionBarSherlock/res/values/abs__themes.xml +++ /dev/null @@ -1,226 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/android-libraries/ActionBarSherlock/res/values/strings.xml b/android-libraries/ActionBarSherlock/res/values/strings.xml deleted file mode 100644 index 43d1652c2..000000000 --- a/android-libraries/ActionBarSherlock/res/values/strings.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - Hello World! - ActionBarSherlock - - \ No newline at end of file diff --git a/android-libraries/ActionBarSherlock/src/android/support/v4/app/_ActionBarSherlockTrojanHorse.java b/android-libraries/ActionBarSherlock/src/android/support/v4/app/_ActionBarSherlockTrojanHorse.java deleted file mode 100644 index 3e3db62b7..000000000 --- a/android-libraries/ActionBarSherlock/src/android/support/v4/app/_ActionBarSherlockTrojanHorse.java +++ /dev/null @@ -1,144 +0,0 @@ -package android.support.v4.app; - -import android.util.Log; -import android.view.View; -import android.view.Window; -import com.actionbarsherlock.ActionBarSherlock.OnCreatePanelMenuListener; -import com.actionbarsherlock.ActionBarSherlock.OnMenuItemSelectedListener; -import com.actionbarsherlock.ActionBarSherlock.OnPreparePanelListener; -import com.actionbarsherlock.view.Menu; -import com.actionbarsherlock.view.MenuInflater; -import com.actionbarsherlock.view.MenuItem; - -import java.util.ArrayList; - -/** I'm in ur package. Stealing ur variables. */ -public abstract class _ActionBarSherlockTrojanHorse extends FragmentActivity implements OnCreatePanelMenuListener, OnPreparePanelListener, OnMenuItemSelectedListener { - private static final boolean DEBUG = false; - private static final String TAG = "_ActionBarSherlockTrojanHorse"; - - /** Fragment interface for menu creation callback. */ - public interface OnCreateOptionsMenuListener { - public void onCreateOptionsMenu(Menu menu, MenuInflater inflater); - } - /** Fragment interface for menu preparation callback. */ - public interface OnPrepareOptionsMenuListener { - public void onPrepareOptionsMenu(Menu menu); - } - /** Fragment interface for menu item selection callback. */ - public interface OnOptionsItemSelectedListener { - public boolean onOptionsItemSelected(MenuItem item); - } - - private ArrayList mCreatedMenus; - - - /////////////////////////////////////////////////////////////////////////// - // Sherlock menu handling - /////////////////////////////////////////////////////////////////////////// - - @Override - public boolean onCreatePanelMenu(int featureId, Menu menu) { - if (DEBUG) Log.d(TAG, "[onCreatePanelMenu] featureId: " + featureId + ", menu: " + menu); - - if (featureId == Window.FEATURE_OPTIONS_PANEL) { - boolean result = onCreateOptionsMenu(menu); - if (DEBUG) Log.d(TAG, "[onCreatePanelMenu] activity create result: " + result); - - MenuInflater inflater = getSupportMenuInflater(); - boolean show = false; - ArrayList newMenus = null; - if (mFragments.mActive != null) { - for (int i = 0; i < mFragments.mAdded.size(); i++) { - Fragment f = mFragments.mAdded.get(i); - if (f != null && !f.mHidden && f.mHasMenu && f.mMenuVisible && f instanceof OnCreateOptionsMenuListener) { - show = true; - ((OnCreateOptionsMenuListener)f).onCreateOptionsMenu(menu, inflater); - if (newMenus == null) { - newMenus = new ArrayList(); - } - newMenus.add(f); - } - } - } - - if (mCreatedMenus != null) { - for (int i = 0; i < mCreatedMenus.size(); i++) { - Fragment f = mCreatedMenus.get(i); - if (newMenus == null || !newMenus.contains(f)) { - f.onDestroyOptionsMenu(); - } - } - } - - mCreatedMenus = newMenus; - - if (DEBUG) Log.d(TAG, "[onCreatePanelMenu] fragments create result: " + show); - result |= show; - - if (DEBUG) Log.d(TAG, "[onCreatePanelMenu] returning " + result); - return result; - } - return false; - } - - @Override - public boolean onPreparePanel(int featureId, View view, Menu menu) { - if (DEBUG) Log.d(TAG, "[onPreparePanel] featureId: " + featureId + ", view: " + view + " menu: " + menu); - - if (featureId == Window.FEATURE_OPTIONS_PANEL) { - boolean result = onPrepareOptionsMenu(menu); - if (DEBUG) Log.d(TAG, "[onPreparePanel] activity prepare result: " + result); - - boolean show = false; - if (mFragments.mActive != null) { - for (int i = 0; i < mFragments.mAdded.size(); i++) { - Fragment f = mFragments.mAdded.get(i); - if (f != null && !f.mHidden && f.mHasMenu && f.mMenuVisible && f instanceof OnPrepareOptionsMenuListener) { - show = true; - ((OnPrepareOptionsMenuListener)f).onPrepareOptionsMenu(menu); - } - } - } - - if (DEBUG) Log.d(TAG, "[onPreparePanel] fragments prepare result: " + show); - result |= show; - - result &= menu.hasVisibleItems(); - if (DEBUG) Log.d(TAG, "[onPreparePanel] returning " + result); - return result; - } - return false; - } - - @Override - public boolean onMenuItemSelected(int featureId, MenuItem item) { - if (DEBUG) Log.d(TAG, "[onMenuItemSelected] featureId: " + featureId + ", item: " + item); - - if (featureId == Window.FEATURE_OPTIONS_PANEL) { - if (onOptionsItemSelected(item)) { - return true; - } - - if (mFragments.mActive != null) { - for (int i = 0; i < mFragments.mAdded.size(); i++) { - Fragment f = mFragments.mAdded.get(i); - if (f != null && !f.mHidden && f.mHasMenu && f.mMenuVisible && f instanceof OnOptionsItemSelectedListener) { - if (((OnOptionsItemSelectedListener)f).onOptionsItemSelected(item)) { - return true; - } - } - } - } - } - return false; - } - - public abstract boolean onCreateOptionsMenu(Menu menu); - - public abstract boolean onPrepareOptionsMenu(Menu menu); - - public abstract boolean onOptionsItemSelected(MenuItem item); - - public abstract MenuInflater getSupportMenuInflater(); -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/ActionBarSherlock.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/ActionBarSherlock.java deleted file mode 100644 index 8340fb591..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/ActionBarSherlock.java +++ /dev/null @@ -1,791 +0,0 @@ -package com.actionbarsherlock; - -import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.util.HashMap; -import java.util.Iterator; -import android.app.Activity; -import android.content.Context; -import android.content.res.Configuration; -import android.os.Build; -import android.os.Bundle; -import android.util.DisplayMetrics; -import android.util.Log; -import android.view.KeyEvent; -import android.view.View; -import android.view.ViewGroup; -import android.view.Window; -import com.actionbarsherlock.app.ActionBar; -import com.actionbarsherlock.internal.ActionBarSherlockCompat; -import com.actionbarsherlock.internal.ActionBarSherlockNative; -import com.actionbarsherlock.view.ActionMode; -import com.actionbarsherlock.view.Menu; -import com.actionbarsherlock.view.MenuInflater; -import com.actionbarsherlock.view.MenuItem; - -/** - *

Helper for implementing the action bar design pattern across all versions - * of Android.

- * - *

This class will manage interaction with a custom action bar based on the - * Android 4.0 source code. The exposed API mirrors that of its native - * counterpart and you should refer to its documentation for instruction.

- * - * @author Jake Wharton - */ -public abstract class ActionBarSherlock { - protected static final String TAG = "ActionBarSherlock"; - protected static final boolean DEBUG = false; - - private static final Class[] CONSTRUCTOR_ARGS = new Class[] { Activity.class, int.class }; - private static final HashMap> IMPLEMENTATIONS = - new HashMap>(); - - static { - //Register our two built-in implementations - registerImplementation(ActionBarSherlockCompat.class); - registerImplementation(ActionBarSherlockNative.class); - } - - - /** - *

Denotes an implementation of ActionBarSherlock which provides an - * action bar-enhanced experience.

- */ - @Target(ElementType.TYPE) - @Retention(RetentionPolicy.RUNTIME) - public @interface Implementation { - static final int DEFAULT_API = -1; - static final int DEFAULT_DPI = -1; - - int api() default DEFAULT_API; - int dpi() default DEFAULT_DPI; - } - - - /** Activity interface for menu creation callback. */ - public interface OnCreatePanelMenuListener { - public boolean onCreatePanelMenu(int featureId, Menu menu); - } - /** Activity interface for menu creation callback. */ - public interface OnCreateOptionsMenuListener { - public boolean onCreateOptionsMenu(Menu menu); - } - /** Activity interface for menu item selection callback. */ - public interface OnMenuItemSelectedListener { - public boolean onMenuItemSelected(int featureId, MenuItem item); - } - /** Activity interface for menu item selection callback. */ - public interface OnOptionsItemSelectedListener { - public boolean onOptionsItemSelected(MenuItem item); - } - /** Activity interface for menu preparation callback. */ - public interface OnPreparePanelListener { - public boolean onPreparePanel(int featureId, View view, Menu menu); - } - /** Activity interface for menu preparation callback. */ - public interface OnPrepareOptionsMenuListener { - public boolean onPrepareOptionsMenu(Menu menu); - } - /** Activity interface for action mode finished callback. */ - public interface OnActionModeFinishedListener { - public void onActionModeFinished(ActionMode mode); - } - /** Activity interface for action mode started callback. */ - public interface OnActionModeStartedListener { - public void onActionModeStarted(ActionMode mode); - } - - - /** - * If set, the logic in these classes will assume that an {@link Activity} - * is dispatching all of the required events to the class. This flag should - * only be used internally or if you are creating your own base activity - * modeled after one of the included types (e.g., {@code SherlockActivity}). - */ - public static final int FLAG_DELEGATE = 1; - - - /** - * Register an ActionBarSherlock implementation. - * - * @param implementationClass Target implementation class which extends - * {@link ActionBarSherlock}. This class must also be annotated with - * {@link Implementation}. - */ - public static void registerImplementation(Class implementationClass) { - if (!implementationClass.isAnnotationPresent(Implementation.class)) { - throw new IllegalArgumentException("Class " + implementationClass.getSimpleName() + " is not annotated with @Implementation"); - } else if (IMPLEMENTATIONS.containsValue(implementationClass)) { - if (DEBUG) Log.w(TAG, "Class " + implementationClass.getSimpleName() + " already registered"); - return; - } - - Implementation impl = implementationClass.getAnnotation(Implementation.class); - if (DEBUG) Log.i(TAG, "Registering " + implementationClass.getSimpleName() + " with qualifier " + impl); - IMPLEMENTATIONS.put(impl, implementationClass); - } - - /** - * Unregister an ActionBarSherlock implementation. This should be - * considered very volatile and you should only use it if you know what - * you are doing. You have been warned. - * - * @param implementationClass Target implementation class. - * @return Boolean indicating whether the class was removed. - */ - public static boolean unregisterImplementation(Class implementationClass) { - return IMPLEMENTATIONS.values().remove(implementationClass); - } - - /** - * Wrap an activity with an action bar abstraction which will enable the - * use of a custom implementation on platforms where a native version does - * not exist. - * - * @param activity Activity to wrap. - * @return Instance to interact with the action bar. - */ - public static ActionBarSherlock wrap(Activity activity) { - return wrap(activity, 0); - } - - /** - * Wrap an activity with an action bar abstraction which will enable the - * use of a custom implementation on platforms where a native version does - * not exist. - * - * @param activity Owning activity. - * @param flags Option flags to control behavior. - * @return Instance to interact with the action bar. - */ - public static ActionBarSherlock wrap(Activity activity, int flags) { - //Create a local implementation map we can modify - HashMap> impls = - new HashMap>(IMPLEMENTATIONS); - boolean hasQualfier; - - /* DPI FILTERING */ - hasQualfier = false; - for (Implementation key : impls.keySet()) { - //Only honor TVDPI as a specific qualifier - if (key.dpi() == DisplayMetrics.DENSITY_TV) { - hasQualfier = true; - break; - } - } - if (hasQualfier) { - final boolean isTvDpi = activity.getResources().getDisplayMetrics().densityDpi == DisplayMetrics.DENSITY_TV; - for (Iterator keys = impls.keySet().iterator(); keys.hasNext(); ) { - int keyDpi = keys.next().dpi(); - if ((isTvDpi && keyDpi != DisplayMetrics.DENSITY_TV) - || (!isTvDpi && keyDpi == DisplayMetrics.DENSITY_TV)) { - keys.remove(); - } - } - } - - /* API FILTERING */ - hasQualfier = false; - for (Implementation key : impls.keySet()) { - if (key.api() != Implementation.DEFAULT_API) { - hasQualfier = true; - break; - } - } - if (hasQualfier) { - final int runtimeApi = Build.VERSION.SDK_INT; - int bestApi = 0; - for (Iterator keys = impls.keySet().iterator(); keys.hasNext(); ) { - int keyApi = keys.next().api(); - if (keyApi > runtimeApi) { - keys.remove(); - } else if (keyApi > bestApi) { - bestApi = keyApi; - } - } - for (Iterator keys = impls.keySet().iterator(); keys.hasNext(); ) { - if (keys.next().api() != bestApi) { - keys.remove(); - } - } - } - - if (impls.size() > 1) { - throw new IllegalStateException("More than one implementation matches configuration."); - } - if (impls.isEmpty()) { - throw new IllegalStateException("No implementations match configuration."); - } - Class impl = impls.values().iterator().next(); - if (DEBUG) Log.i(TAG, "Using implementation: " + impl.getSimpleName()); - - try { - Constructor ctor = impl.getConstructor(CONSTRUCTOR_ARGS); - return ctor.newInstance(activity, flags); - } catch (NoSuchMethodException e) { - throw new RuntimeException(e); - } catch (IllegalArgumentException e) { - throw new RuntimeException(e); - } catch (InstantiationException e) { - throw new RuntimeException(e); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } catch (InvocationTargetException e) { - throw new RuntimeException(e); - } - } - - - /** Activity which is displaying the action bar. Also used for context. */ - protected final Activity mActivity; - /** Whether delegating actions for the activity or managing ourselves. */ - protected final boolean mIsDelegate; - - /** Reference to our custom menu inflater which supports action items. */ - protected MenuInflater mMenuInflater; - - - - protected ActionBarSherlock(Activity activity, int flags) { - if (DEBUG) Log.d(TAG, "[] activity: " + activity + ", flags: " + flags); - - mActivity = activity; - mIsDelegate = (flags & FLAG_DELEGATE) != 0; - } - - - /** - * Get the current action bar instance. - * - * @return Action bar instance. - */ - public abstract ActionBar getActionBar(); - - - /////////////////////////////////////////////////////////////////////////// - // Lifecycle and interaction callbacks when delegating - /////////////////////////////////////////////////////////////////////////// - - /** - * Notify action bar of a configuration change event. Should be dispatched - * after the call to the superclass implementation. - * - *
-     * @Override
-     * public void onConfigurationChanged(Configuration newConfig) {
-     *     super.onConfigurationChanged(newConfig);
-     *     mSherlock.dispatchConfigurationChanged(newConfig);
-     * }
-     * 
- * - * @param newConfig The new device configuration. - */ - public void dispatchConfigurationChanged(Configuration newConfig) {} - - /** - * Notify the action bar that the activity has finished its resuming. This - * should be dispatched after the call to the superclass implementation. - * - *
-     * @Override
-     * protected void onPostResume() {
-     *     super.onPostResume();
-     *     mSherlock.dispatchPostResume();
-     * }
-     * 
- */ - public void dispatchPostResume() {} - - /** - * Notify the action bar that the activity is pausing. This should be - * dispatched before the call to the superclass implementation. - * - *
-     * @Override
-     * protected void onPause() {
-     *     mSherlock.dispatchPause();
-     *     super.onPause();
-     * }
-     * 
- */ - public void dispatchPause() {} - - /** - * Notify the action bar that the activity is stopping. This should be - * called before the superclass implementation. - * - *

- * @Override - * protected void onStop() { - * mSherlock.dispatchStop(); - * super.onStop(); - * } - *

- */ - public void dispatchStop() {} - - /** - * Indicate that the menu should be recreated by calling - * {@link OnCreateOptionsMenuListener#onCreateOptionsMenu(com.actionbarsherlock.view.Menu)}. - */ - public abstract void dispatchInvalidateOptionsMenu(); - - /** - * Notify the action bar that it should display its overflow menu if it is - * appropriate for the device. The implementation should conditionally - * call the superclass method only if this method returns {@code false}. - * - *

- * @Override - * public void openOptionsMenu() { - * if (!mSherlock.dispatchOpenOptionsMenu()) { - * super.openOptionsMenu(); - * } - * } - *

- * - * @return {@code true} if the opening of the menu was handled internally. - */ - public boolean dispatchOpenOptionsMenu() { - return false; - } - - /** - * Notify the action bar that it should close its overflow menu if it is - * appropriate for the device. This implementation should conditionally - * call the superclass method only if this method returns {@code false}. - * - *
-     * @Override
-     * public void closeOptionsMenu() {
-     *     if (!mSherlock.dispatchCloseOptionsMenu()) {
-     *         super.closeOptionsMenu();
-     *     }
-     * }
-     * 
- * - * @return {@code true} if the closing of the menu was handled internally. - */ - public boolean dispatchCloseOptionsMenu() { - return false; - } - - /** - * Notify the class that the activity has finished its creation. This - * should be called after the superclass implementation. - * - *
-     * @Override
-     * protected void onPostCreate(Bundle savedInstanceState) {
-     *     mSherlock.dispatchPostCreate(savedInstanceState);
-     *     super.onPostCreate(savedInstanceState);
-     * }
-     * 
- * - * @param savedInstanceState If the activity is being re-initialized after - * previously being shut down then this Bundle - * contains the data it most recently supplied in - * {@link Activity#}onSaveInstanceState(Bundle)}. - * Note: Otherwise it is null. - */ - public void dispatchPostCreate(Bundle savedInstanceState) {} - - /** - * Notify the action bar that the title has changed and the action bar - * should be updated to reflect the change. This should be called before - * the superclass implementation. - * - *
-     *  @Override
-     *  protected void onTitleChanged(CharSequence title, int color) {
-     *      mSherlock.dispatchTitleChanged(title, color);
-     *      super.onTitleChanged(title, color);
-     *  }
-     * 
- * - * @param title New activity title. - * @param color New activity color. - */ - public void dispatchTitleChanged(CharSequence title, int color) {} - - /** - * Notify the action bar the user has created a key event. This is used to - * toggle the display of the overflow action item with the menu key and to - * close the action mode or expanded action item with the back key. - * - *
-     * @Override
-     * public boolean dispatchKeyEvent(KeyEvent event) {
-     *     if (mSherlock.dispatchKeyEvent(event)) {
-     *         return true;
-     *     }
-     *     return super.dispatchKeyEvent(event);
-     * }
-     * 
- * - * @param event Description of the key event. - * @return {@code true} if the event was handled. - */ - public boolean dispatchKeyEvent(KeyEvent event) { - return false; - } - - /** - * Notify the action bar that the Activity has triggered a menu creation - * which should happen on the conclusion of {@link Activity#onCreate}. This - * will be used to gain a reference to the native menu for native and - * overflow binding as well as to indicate when compatibility create should - * occur for the first time. - * - * @param menu Activity native menu. - * @return {@code true} since we always want to say that we have a native - */ - public abstract boolean dispatchCreateOptionsMenu(android.view.Menu menu); - - /** - * Notify the action bar that the Activity has triggered a menu preparation - * which usually means that the user has requested the overflow menu via a - * hardware menu key. You should return the result of this method call and - * not call the superclass implementation. - * - *

- * @Override - * public final boolean onPrepareOptionsMenu(android.view.Menu menu) { - * return mSherlock.dispatchPrepareOptionsMenu(menu); - * } - *

- * - * @param menu Activity native menu. - * @return {@code true} if menu display should proceed. - */ - public abstract boolean dispatchPrepareOptionsMenu(android.view.Menu menu); - - /** - * Notify the action bar that a native options menu item has been selected. - * The implementation should return the result of this method call. - * - *

- * @Override - * public final boolean onOptionsItemSelected(android.view.MenuItem item) { - * return mSherlock.dispatchOptionsItemSelected(item); - * } - *

- * - * @param item Options menu item. - * @return @{code true} if the selection was handled. - */ - public abstract boolean dispatchOptionsItemSelected(android.view.MenuItem item); - - /** - * Notify the action bar that the overflow menu has been opened. The - * implementation should conditionally return {@code true} if this method - * returns {@code true}, otherwise return the result of the superclass - * method. - * - *

- * @Override - * public final boolean onMenuOpened(int featureId, android.view.Menu menu) { - * if (mSherlock.dispatchMenuOpened(featureId, menu)) { - * return true; - * } - * return super.onMenuOpened(featureId, menu); - * } - *

- * - * @param featureId Window feature which triggered the event. - * @param menu Activity native menu. - * @return {@code true} if the event was handled by this method. - */ - public boolean dispatchMenuOpened(int featureId, android.view.Menu menu) { - return false; - } - - /** - * Notify the action bar that the overflow menu has been closed. This - * method should be called before the superclass implementation. - * - *

- * @Override - * public void onPanelClosed(int featureId, android.view.Menu menu) { - * mSherlock.dispatchPanelClosed(featureId, menu); - * super.onPanelClosed(featureId, menu); - * } - *

- * - * @param featureId - * @param menu - */ - public void dispatchPanelClosed(int featureId, android.view.Menu menu) {} - - /** - * Notify the action bar that the activity has been destroyed. This method - * should be called before the superclass implementation. - * - *

- * @Override - * public void onDestroy() { - * mSherlock.dispatchDestroy(); - * super.onDestroy(); - * } - *

- */ - public void dispatchDestroy() {} - - - /////////////////////////////////////////////////////////////////////////// - /////////////////////////////////////////////////////////////////////////// - - - /** - * Internal method to trigger the menu creation process. - * - * @return {@code true} if menu creation should proceed. - */ - protected final boolean callbackCreateOptionsMenu(Menu menu) { - if (DEBUG) Log.d(TAG, "[callbackCreateOptionsMenu] menu: " + menu); - - boolean result = true; - if (mActivity instanceof OnCreatePanelMenuListener) { - OnCreatePanelMenuListener listener = (OnCreatePanelMenuListener)mActivity; - result = listener.onCreatePanelMenu(Window.FEATURE_OPTIONS_PANEL, menu); - } else if (mActivity instanceof OnCreateOptionsMenuListener) { - OnCreateOptionsMenuListener listener = (OnCreateOptionsMenuListener)mActivity; - result = listener.onCreateOptionsMenu(menu); - } - - if (DEBUG) Log.d(TAG, "[callbackCreateOptionsMenu] returning " + result); - return result; - } - - /** - * Internal method to trigger the menu preparation process. - * - * @return {@code true} if menu preparation should proceed. - */ - protected final boolean callbackPrepareOptionsMenu(Menu menu) { - if (DEBUG) Log.d(TAG, "[callbackPrepareOptionsMenu] menu: " + menu); - - boolean result = true; - if (mActivity instanceof OnPreparePanelListener) { - OnPreparePanelListener listener = (OnPreparePanelListener)mActivity; - result = listener.onPreparePanel(Window.FEATURE_OPTIONS_PANEL, null, menu); - } else if (mActivity instanceof OnPrepareOptionsMenuListener) { - OnPrepareOptionsMenuListener listener = (OnPrepareOptionsMenuListener)mActivity; - result = listener.onPrepareOptionsMenu(menu); - } - - if (DEBUG) Log.d(TAG, "[callbackPrepareOptionsMenu] returning " + result); - return result; - } - - /** - * Internal method for dispatching options menu selection to the owning - * activity callback. - * - * @param item Selected options menu item. - * @return {@code true} if the item selection was handled in the callback. - */ - protected final boolean callbackOptionsItemSelected(MenuItem item) { - if (DEBUG) Log.d(TAG, "[callbackOptionsItemSelected] item: " + item.getTitleCondensed()); - - boolean result = false; - if (mActivity instanceof OnMenuItemSelectedListener) { - OnMenuItemSelectedListener listener = (OnMenuItemSelectedListener)mActivity; - result = listener.onMenuItemSelected(Window.FEATURE_OPTIONS_PANEL, item); - } else if (mActivity instanceof OnOptionsItemSelectedListener) { - OnOptionsItemSelectedListener listener = (OnOptionsItemSelectedListener)mActivity; - result = listener.onOptionsItemSelected(item); - } - - if (DEBUG) Log.d(TAG, "[callbackOptionsItemSelected] returning " + result); - return result; - } - - - /////////////////////////////////////////////////////////////////////////// - /////////////////////////////////////////////////////////////////////////// - - - /** - * Query for the availability of a certain feature. - * - * @param featureId The feature ID to check. - * @return {@code true} if feature is enabled, {@code false} otherwise. - */ - public abstract boolean hasFeature(int featureId); - - /** - * Enable extended screen features. This must be called before - * {@code setContentView()}. May be called as many times as desired as long - * as it is before {@code setContentView()}. If not called, no extended - * features will be available. You can not turn off a feature once it is - * requested. - * - * @param featureId The desired features, defined as constants by Window. - * @return Returns true if the requested feature is supported and now - * enabled. - */ - public abstract boolean requestFeature(int featureId); - - /** - * Set extra options that will influence the UI for this window. - * - * @param uiOptions Flags specifying extra options for this window. - */ - public abstract void setUiOptions(int uiOptions); - - /** - * Set extra options that will influence the UI for this window. Only the - * bits filtered by mask will be modified. - * - * @param uiOptions Flags specifying extra options for this window. - * @param mask Flags specifying which options should be modified. Others - * will remain unchanged. - */ - public abstract void setUiOptions(int uiOptions, int mask); - - /** - * Set the content of the activity inside the action bar. - * - * @param layoutResId Layout resource ID. - */ - public abstract void setContentView(int layoutResId); - - /** - * Set the content of the activity inside the action bar. - * - * @param view The desired content to display. - */ - public void setContentView(View view) { - if (DEBUG) Log.d(TAG, "[setContentView] view: " + view); - - setContentView(view, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT)); - } - - /** - * Set the content of the activity inside the action bar. - * - * @param view The desired content to display. - * @param params Layout parameters to apply to the view. - */ - public abstract void setContentView(View view, ViewGroup.LayoutParams params); - - /** - * Variation on {@link #setContentView(android.view.View, android.view.ViewGroup.LayoutParams)} - * to add an additional content view to the screen. Added after any - * existing ones on the screen -- existing views are NOT removed. - * - * @param view The desired content to display. - * @param params Layout parameters for the view. - */ - public abstract void addContentView(View view, ViewGroup.LayoutParams params); - - /** - * Change the title associated with this activity. - */ - public abstract void setTitle(CharSequence title); - - /** - * Change the title associated with this activity. - */ - public void setTitle(int resId) { - if (DEBUG) Log.d(TAG, "[setTitle] resId: " + resId); - - setTitle(mActivity.getString(resId)); - } - - /** - * Sets the visibility of the progress bar in the title. - *

- * In order for the progress bar to be shown, the feature must be requested - * via {@link #requestWindowFeature(int)}. - * - * @param visible Whether to show the progress bars in the title. - */ - public abstract void setProgressBarVisibility(boolean visible); - - /** - * Sets the visibility of the indeterminate progress bar in the title. - *

- * In order for the progress bar to be shown, the feature must be requested - * via {@link #requestWindowFeature(int)}. - * - * @param visible Whether to show the progress bars in the title. - */ - public abstract void setProgressBarIndeterminateVisibility(boolean visible); - - /** - * Sets whether the horizontal progress bar in the title should be indeterminate (the circular - * is always indeterminate). - *

- * In order for the progress bar to be shown, the feature must be requested - * via {@link #requestWindowFeature(int)}. - * - * @param indeterminate Whether the horizontal progress bar should be indeterminate. - */ - public abstract void setProgressBarIndeterminate(boolean indeterminate); - - /** - * Sets the progress for the progress bars in the title. - *

- * In order for the progress bar to be shown, the feature must be requested - * via {@link #requestWindowFeature(int)}. - * - * @param progress The progress for the progress bar. Valid ranges are from - * 0 to 10000 (both inclusive). If 10000 is given, the progress - * bar will be completely filled and will fade out. - */ - public abstract void setProgress(int progress); - - /** - * Sets the secondary progress for the progress bar in the title. This - * progress is drawn between the primary progress (set via - * {@link #setProgress(int)} and the background. It can be ideal for media - * scenarios such as showing the buffering progress while the default - * progress shows the play progress. - *

- * In order for the progress bar to be shown, the feature must be requested - * via {@link #requestWindowFeature(int)}. - * - * @param secondaryProgress The secondary progress for the progress bar. Valid ranges are from - * 0 to 10000 (both inclusive). - */ - public abstract void setSecondaryProgress(int secondaryProgress); - - /** - * Get a menu inflater instance which supports the newer menu attributes. - * - * @return Menu inflater instance. - */ - public MenuInflater getMenuInflater() { - if (DEBUG) Log.d(TAG, "[getMenuInflater]"); - - // Make sure that action views can get an appropriate theme. - if (mMenuInflater == null) { - if (getActionBar() != null) { - mMenuInflater = new MenuInflater(getThemedContext()); - } else { - mMenuInflater = new MenuInflater(mActivity); - } - } - return mMenuInflater; - } - - protected abstract Context getThemedContext(); - - /** - * Start an action mode. - * - * @param callback Callback that will manage lifecycle events for this - * context mode. - * @return The ContextMode that was started, or null if it was canceled. - * @see ActionMode - */ - public abstract ActionMode startActionMode(ActionMode.Callback callback); -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/app/ActionBar.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/app/ActionBar.java deleted file mode 100644 index 2497d24ff..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/app/ActionBar.java +++ /dev/null @@ -1,947 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.app; - -import android.content.Context; -import android.graphics.drawable.Drawable; -import android.support.v4.app.FragmentTransaction; -import android.util.AttributeSet; -import android.view.Gravity; -import android.view.View; -import android.view.ViewDebug; -import android.view.ViewGroup; -import android.view.ViewGroup.MarginLayoutParams; -import android.widget.SpinnerAdapter; - -/** - * A window feature at the top of the activity that may display the activity title, navigation - * modes, and other interactive items. - *

Beginning with Android 3.0 (API level 11), the action bar appears at the top of an - * activity's window when the activity uses the system's {@link - * android.R.style#Theme_Holo Holo} theme (or one of its descendant themes), which is the default. - * You may otherwise add the action bar by calling {@link - * android.view.Window#requestFeature requestFeature(FEATURE_ACTION_BAR)} or by declaring it in a - * custom theme with the {@link android.R.styleable#Theme_windowActionBar windowActionBar} property. - *

By default, the action bar shows the application icon on - * the left, followed by the activity title. If your activity has an options menu, you can make - * select items accessible directly from the action bar as "action items". You can also - * modify various characteristics of the action bar or remove it completely.

- *

From your activity, you can retrieve an instance of {@link ActionBar} by calling {@link - * android.app.Activity#getActionBar getActionBar()}.

- *

In some cases, the action bar may be overlayed by another bar that enables contextual actions, - * using an {@link android.view.ActionMode}. For example, when the user selects one or more items in - * your activity, you can enable an action mode that offers actions specific to the selected - * items, with a UI that temporarily replaces the action bar. Although the UI may occupy the - * same space, the {@link android.view.ActionMode} APIs are distinct and independent from those for - * {@link ActionBar}. - *

- */ -public abstract class ActionBar { - /** - * Standard navigation mode. Consists of either a logo or icon - * and title text with an optional subtitle. Clicking any of these elements - * will dispatch onOptionsItemSelected to the host Activity with - * a MenuItem with item ID android.R.id.home. - */ - public static final int NAVIGATION_MODE_STANDARD = android.app.ActionBar.NAVIGATION_MODE_STANDARD; - - /** - * List navigation mode. Instead of static title text this mode - * presents a list menu for navigation within the activity. - * e.g. this might be presented to the user as a dropdown list. - */ - public static final int NAVIGATION_MODE_LIST = android.app.ActionBar.NAVIGATION_MODE_LIST; - - /** - * Tab navigation mode. Instead of static title text this mode - * presents a series of tabs for navigation within the activity. - */ - public static final int NAVIGATION_MODE_TABS = android.app.ActionBar.NAVIGATION_MODE_TABS; - - /** - * Use logo instead of icon if available. This flag will cause appropriate - * navigation modes to use a wider logo in place of the standard icon. - * - * @see #setDisplayOptions(int) - * @see #setDisplayOptions(int, int) - */ - public static final int DISPLAY_USE_LOGO = android.app.ActionBar.DISPLAY_USE_LOGO; - - /** - * Show 'home' elements in this action bar, leaving more space for other - * navigation elements. This includes logo and icon. - * - * @see #setDisplayOptions(int) - * @see #setDisplayOptions(int, int) - */ - public static final int DISPLAY_SHOW_HOME = android.app.ActionBar.DISPLAY_SHOW_HOME; - - /** - * Display the 'home' element such that it appears as an 'up' affordance. - * e.g. show an arrow to the left indicating the action that will be taken. - * - * Set this flag if selecting the 'home' button in the action bar to return - * up by a single level in your UI rather than back to the top level or front page. - * - *

Setting this option will implicitly enable interaction with the home/up - * button. See {@link #setHomeButtonEnabled(boolean)}. - * - * @see #setDisplayOptions(int) - * @see #setDisplayOptions(int, int) - */ - public static final int DISPLAY_HOME_AS_UP = android.app.ActionBar.DISPLAY_HOME_AS_UP; - - /** - * Show the activity title and subtitle, if present. - * - * @see #setTitle(CharSequence) - * @see #setTitle(int) - * @see #setSubtitle(CharSequence) - * @see #setSubtitle(int) - * @see #setDisplayOptions(int) - * @see #setDisplayOptions(int, int) - */ - public static final int DISPLAY_SHOW_TITLE = android.app.ActionBar.DISPLAY_SHOW_TITLE; - - /** - * Show the custom view if one has been set. - * @see #setCustomView(View) - * @see #setDisplayOptions(int) - * @see #setDisplayOptions(int, int) - */ - public static final int DISPLAY_SHOW_CUSTOM = android.app.ActionBar.DISPLAY_SHOW_CUSTOM; - - /** - * Set the action bar into custom navigation mode, supplying a view - * for custom navigation. - * - * Custom navigation views appear between the application icon and - * any action buttons and may use any space available there. Common - * use cases for custom navigation views might include an auto-suggesting - * address bar for a browser or other navigation mechanisms that do not - * translate well to provided navigation modes. - * - * @param view Custom navigation view to place in the ActionBar. - */ - public abstract void setCustomView(View view); - - /** - * Set the action bar into custom navigation mode, supplying a view - * for custom navigation. - * - *

Custom navigation views appear between the application icon and - * any action buttons and may use any space available there. Common - * use cases for custom navigation views might include an auto-suggesting - * address bar for a browser or other navigation mechanisms that do not - * translate well to provided navigation modes.

- * - *

The display option {@link #DISPLAY_SHOW_CUSTOM} must be set for - * the custom view to be displayed.

- * - * @param view Custom navigation view to place in the ActionBar. - * @param layoutParams How this custom view should layout in the bar. - * - * @see #setDisplayOptions(int, int) - */ - public abstract void setCustomView(View view, LayoutParams layoutParams); - - /** - * Set the action bar into custom navigation mode, supplying a view - * for custom navigation. - * - *

Custom navigation views appear between the application icon and - * any action buttons and may use any space available there. Common - * use cases for custom navigation views might include an auto-suggesting - * address bar for a browser or other navigation mechanisms that do not - * translate well to provided navigation modes.

- * - *

The display option {@link #DISPLAY_SHOW_CUSTOM} must be set for - * the custom view to be displayed.

- * - * @param resId Resource ID of a layout to inflate into the ActionBar. - * - * @see #setDisplayOptions(int, int) - */ - public abstract void setCustomView(int resId); - - /** - * Set the icon to display in the 'home' section of the action bar. - * The action bar will use an icon specified by its style or the - * activity icon by default. - * - * Whether the home section shows an icon or logo is controlled - * by the display option {@link #DISPLAY_USE_LOGO}. - * - * @param resId Resource ID of a drawable to show as an icon. - * - * @see #setDisplayUseLogoEnabled(boolean) - * @see #setDisplayShowHomeEnabled(boolean) - */ - public abstract void setIcon(int resId); - - /** - * Set the icon to display in the 'home' section of the action bar. - * The action bar will use an icon specified by its style or the - * activity icon by default. - * - * Whether the home section shows an icon or logo is controlled - * by the display option {@link #DISPLAY_USE_LOGO}. - * - * @param icon Drawable to show as an icon. - * - * @see #setDisplayUseLogoEnabled(boolean) - * @see #setDisplayShowHomeEnabled(boolean) - */ - public abstract void setIcon(Drawable icon); - - /** - * Set the logo to display in the 'home' section of the action bar. - * The action bar will use a logo specified by its style or the - * activity logo by default. - * - * Whether the home section shows an icon or logo is controlled - * by the display option {@link #DISPLAY_USE_LOGO}. - * - * @param resId Resource ID of a drawable to show as a logo. - * - * @see #setDisplayUseLogoEnabled(boolean) - * @see #setDisplayShowHomeEnabled(boolean) - */ - public abstract void setLogo(int resId); - - /** - * Set the logo to display in the 'home' section of the action bar. - * The action bar will use a logo specified by its style or the - * activity logo by default. - * - * Whether the home section shows an icon or logo is controlled - * by the display option {@link #DISPLAY_USE_LOGO}. - * - * @param logo Drawable to show as a logo. - * - * @see #setDisplayUseLogoEnabled(boolean) - * @see #setDisplayShowHomeEnabled(boolean) - */ - public abstract void setLogo(Drawable logo); - - /** - * Set the adapter and navigation callback for list navigation mode. - * - * The supplied adapter will provide views for the expanded list as well as - * the currently selected item. (These may be displayed differently.) - * - * The supplied OnNavigationListener will alert the application when the user - * changes the current list selection. - * - * @param adapter An adapter that will provide views both to display - * the current navigation selection and populate views - * within the dropdown navigation menu. - * @param callback An OnNavigationListener that will receive events when the user - * selects a navigation item. - */ - public abstract void setListNavigationCallbacks(SpinnerAdapter adapter, - OnNavigationListener callback); - - /** - * Set the selected navigation item in list or tabbed navigation modes. - * - * @param position Position of the item to select. - */ - public abstract void setSelectedNavigationItem(int position); - - /** - * Get the position of the selected navigation item in list or tabbed navigation modes. - * - * @return Position of the selected item. - */ - public abstract int getSelectedNavigationIndex(); - - /** - * Get the number of navigation items present in the current navigation mode. - * - * @return Number of navigation items. - */ - public abstract int getNavigationItemCount(); - - /** - * Set the action bar's title. This will only be displayed if - * {@link #DISPLAY_SHOW_TITLE} is set. - * - * @param title Title to set - * - * @see #setTitle(int) - * @see #setDisplayOptions(int, int) - */ - public abstract void setTitle(CharSequence title); - - /** - * Set the action bar's title. This will only be displayed if - * {@link #DISPLAY_SHOW_TITLE} is set. - * - * @param resId Resource ID of title string to set - * - * @see #setTitle(CharSequence) - * @see #setDisplayOptions(int, int) - */ - public abstract void setTitle(int resId); - - /** - * Set the action bar's subtitle. This will only be displayed if - * {@link #DISPLAY_SHOW_TITLE} is set. Set to null to disable the - * subtitle entirely. - * - * @param subtitle Subtitle to set - * - * @see #setSubtitle(int) - * @see #setDisplayOptions(int, int) - */ - public abstract void setSubtitle(CharSequence subtitle); - - /** - * Set the action bar's subtitle. This will only be displayed if - * {@link #DISPLAY_SHOW_TITLE} is set. - * - * @param resId Resource ID of subtitle string to set - * - * @see #setSubtitle(CharSequence) - * @see #setDisplayOptions(int, int) - */ - public abstract void setSubtitle(int resId); - - /** - * Set display options. This changes all display option bits at once. To change - * a limited subset of display options, see {@link #setDisplayOptions(int, int)}. - * - * @param options A combination of the bits defined by the DISPLAY_ constants - * defined in ActionBar. - */ - public abstract void setDisplayOptions(int options); - - /** - * Set selected display options. Only the options specified by mask will be changed. - * To change all display option bits at once, see {@link #setDisplayOptions(int)}. - * - *

Example: setDisplayOptions(0, DISPLAY_SHOW_HOME) will disable the - * {@link #DISPLAY_SHOW_HOME} option. - * setDisplayOptions(DISPLAY_SHOW_HOME, DISPLAY_SHOW_HOME | DISPLAY_USE_LOGO) - * will enable {@link #DISPLAY_SHOW_HOME} and disable {@link #DISPLAY_USE_LOGO}. - * - * @param options A combination of the bits defined by the DISPLAY_ constants - * defined in ActionBar. - * @param mask A bit mask declaring which display options should be changed. - */ - public abstract void setDisplayOptions(int options, int mask); - - /** - * Set whether to display the activity logo rather than the activity icon. - * A logo is often a wider, more detailed image. - * - *

To set several display options at once, see the setDisplayOptions methods. - * - * @param useLogo true to use the activity logo, false to use the activity icon. - * - * @see #setDisplayOptions(int) - * @see #setDisplayOptions(int, int) - */ - public abstract void setDisplayUseLogoEnabled(boolean useLogo); - - /** - * Set whether to include the application home affordance in the action bar. - * Home is presented as either an activity icon or logo. - * - *

To set several display options at once, see the setDisplayOptions methods. - * - * @param showHome true to show home, false otherwise. - * - * @see #setDisplayOptions(int) - * @see #setDisplayOptions(int, int) - */ - public abstract void setDisplayShowHomeEnabled(boolean showHome); - - /** - * Set whether home should be displayed as an "up" affordance. - * Set this to true if selecting "home" returns up by a single level in your UI - * rather than back to the top level or front page. - * - *

To set several display options at once, see the setDisplayOptions methods. - * - * @param showHomeAsUp true to show the user that selecting home will return one - * level up rather than to the top level of the app. - * - * @see #setDisplayOptions(int) - * @see #setDisplayOptions(int, int) - */ - public abstract void setDisplayHomeAsUpEnabled(boolean showHomeAsUp); - - /** - * Set whether an activity title/subtitle should be displayed. - * - *

To set several display options at once, see the setDisplayOptions methods. - * - * @param showTitle true to display a title/subtitle if present. - * - * @see #setDisplayOptions(int) - * @see #setDisplayOptions(int, int) - */ - public abstract void setDisplayShowTitleEnabled(boolean showTitle); - - /** - * Set whether a custom view should be displayed, if set. - * - *

To set several display options at once, see the setDisplayOptions methods. - * - * @param showCustom true if the currently set custom view should be displayed, false otherwise. - * - * @see #setDisplayOptions(int) - * @see #setDisplayOptions(int, int) - */ - public abstract void setDisplayShowCustomEnabled(boolean showCustom); - - /** - * Set the ActionBar's background. This will be used for the primary - * action bar. - * - * @param d Background drawable - * @see #setStackedBackgroundDrawable(Drawable) - * @see #setSplitBackgroundDrawable(Drawable) - */ - public abstract void setBackgroundDrawable(Drawable d); - - /** - * Set the ActionBar's stacked background. This will appear - * in the second row/stacked bar on some devices and configurations. - * - * @param d Background drawable for the stacked row - */ - public void setStackedBackgroundDrawable(Drawable d) { } - - /** - * Set the ActionBar's split background. This will appear in - * the split action bar containing menu-provided action buttons - * on some devices and configurations. - *

You can enable split action bar with {@link android.R.attr#uiOptions} - * - * @param d Background drawable for the split bar - */ - public void setSplitBackgroundDrawable(Drawable d) { } - - /** - * @return The current custom view. - */ - public abstract View getCustomView(); - - /** - * Returns the current ActionBar title in standard mode. - * Returns null if {@link #getNavigationMode()} would not return - * {@link #NAVIGATION_MODE_STANDARD}. - * - * @return The current ActionBar title or null. - */ - public abstract CharSequence getTitle(); - - /** - * Returns the current ActionBar subtitle in standard mode. - * Returns null if {@link #getNavigationMode()} would not return - * {@link #NAVIGATION_MODE_STANDARD}. - * - * @return The current ActionBar subtitle or null. - */ - public abstract CharSequence getSubtitle(); - - /** - * Returns the current navigation mode. The result will be one of: - *

    - *
  • {@link #NAVIGATION_MODE_STANDARD}
  • - *
  • {@link #NAVIGATION_MODE_LIST}
  • - *
  • {@link #NAVIGATION_MODE_TABS}
  • - *
- * - * @return The current navigation mode. - */ - public abstract int getNavigationMode(); - - /** - * Set the current navigation mode. - * - * @param mode The new mode to set. - * @see #NAVIGATION_MODE_STANDARD - * @see #NAVIGATION_MODE_LIST - * @see #NAVIGATION_MODE_TABS - */ - public abstract void setNavigationMode(int mode); - - /** - * @return The current set of display options. - */ - public abstract int getDisplayOptions(); - - /** - * Create and return a new {@link Tab}. - * This tab will not be included in the action bar until it is added. - * - *

Very often tabs will be used to switch between {@link Fragment} - * objects. Here is a typical implementation of such tabs:

- * - * {@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentTabs.java - * complete} - * - * @return A new Tab - * - * @see #addTab(Tab) - */ - public abstract Tab newTab(); - - /** - * Add a tab for use in tabbed navigation mode. The tab will be added at the end of the list. - * If this is the first tab to be added it will become the selected tab. - * - * @param tab Tab to add - */ - public abstract void addTab(Tab tab); - - /** - * Add a tab for use in tabbed navigation mode. The tab will be added at the end of the list. - * - * @param tab Tab to add - * @param setSelected True if the added tab should become the selected tab. - */ - public abstract void addTab(Tab tab, boolean setSelected); - - /** - * Add a tab for use in tabbed navigation mode. The tab will be inserted at - * position. If this is the first tab to be added it will become - * the selected tab. - * - * @param tab The tab to add - * @param position The new position of the tab - */ - public abstract void addTab(Tab tab, int position); - - /** - * Add a tab for use in tabbed navigation mode. The tab will be insterted at - * position. - * - * @param tab The tab to add - * @param position The new position of the tab - * @param setSelected True if the added tab should become the selected tab. - */ - public abstract void addTab(Tab tab, int position, boolean setSelected); - - /** - * Remove a tab from the action bar. If the removed tab was selected it will be deselected - * and another tab will be selected if present. - * - * @param tab The tab to remove - */ - public abstract void removeTab(Tab tab); - - /** - * Remove a tab from the action bar. If the removed tab was selected it will be deselected - * and another tab will be selected if present. - * - * @param position Position of the tab to remove - */ - public abstract void removeTabAt(int position); - - /** - * Remove all tabs from the action bar and deselect the current tab. - */ - public abstract void removeAllTabs(); - - /** - * Select the specified tab. If it is not a child of this action bar it will be added. - * - *

Note: If you want to select by index, use {@link #setSelectedNavigationItem(int)}.

- * - * @param tab Tab to select - */ - public abstract void selectTab(Tab tab); - - /** - * Returns the currently selected tab if in tabbed navigation mode and there is at least - * one tab present. - * - * @return The currently selected tab or null - */ - public abstract Tab getSelectedTab(); - - /** - * Returns the tab at the specified index. - * - * @param index Index value in the range 0-get - * @return - */ - public abstract Tab getTabAt(int index); - - /** - * Returns the number of tabs currently registered with the action bar. - * @return Tab count - */ - public abstract int getTabCount(); - - /** - * Retrieve the current height of the ActionBar. - * - * @return The ActionBar's height - */ - public abstract int getHeight(); - - /** - * Show the ActionBar if it is not currently showing. - * If the window hosting the ActionBar does not have the feature - * {@link Window#FEATURE_ACTION_BAR_OVERLAY} it will resize application - * content to fit the new space available. - */ - public abstract void show(); - - /** - * Hide the ActionBar if it is currently showing. - * If the window hosting the ActionBar does not have the feature - * {@link Window#FEATURE_ACTION_BAR_OVERLAY} it will resize application - * content to fit the new space available. - */ - public abstract void hide(); - - /** - * @return true if the ActionBar is showing, false otherwise. - */ - public abstract boolean isShowing(); - - /** - * Add a listener that will respond to menu visibility change events. - * - * @param listener The new listener to add - */ - public abstract void addOnMenuVisibilityListener(OnMenuVisibilityListener listener); - - /** - * Remove a menu visibility listener. This listener will no longer receive menu - * visibility change events. - * - * @param listener A listener to remove that was previously added - */ - public abstract void removeOnMenuVisibilityListener(OnMenuVisibilityListener listener); - - /** - * Enable or disable the "home" button in the corner of the action bar. (Note that this - * is the application home/up affordance on the action bar, not the systemwide home - * button.) - * - *

This defaults to true for packages targeting < API 14. For packages targeting - * API 14 or greater, the application should call this method to enable interaction - * with the home/up affordance. - * - *

Setting the {@link #DISPLAY_HOME_AS_UP} display option will automatically enable - * the home button. - * - * @param enabled true to enable the home button, false to disable the home button. - */ - public void setHomeButtonEnabled(boolean enabled) { } - - /** - * Returns a {@link Context} with an appropriate theme for creating views that - * will appear in the action bar. If you are inflating or instantiating custom views - * that will appear in an action bar, you should use the Context returned by this method. - * (This includes adapters used for list navigation mode.) - * This will ensure that views contrast properly against the action bar. - * - * @return A themed Context for creating views - */ - public Context getThemedContext() { return null; } - - /** - * Listener interface for ActionBar navigation events. - */ - public interface OnNavigationListener { - /** - * This method is called whenever a navigation item in your action bar - * is selected. - * - * @param itemPosition Position of the item clicked. - * @param itemId ID of the item clicked. - * @return True if the event was handled, false otherwise. - */ - public boolean onNavigationItemSelected(int itemPosition, long itemId); - } - - /** - * Listener for receiving events when action bar menus are shown or hidden. - */ - public interface OnMenuVisibilityListener { - /** - * Called when an action bar menu is shown or hidden. Applications may want to use - * this to tune auto-hiding behavior for the action bar or pause/resume video playback, - * gameplay, or other activity within the main content area. - * - * @param isVisible True if an action bar menu is now visible, false if no action bar - * menus are visible. - */ - public void onMenuVisibilityChanged(boolean isVisible); - } - - /** - * A tab in the action bar. - * - *

Tabs manage the hiding and showing of {@link Fragment}s. - */ - public static abstract class Tab { - /** - * An invalid position for a tab. - * - * @see #getPosition() - */ - public static final int INVALID_POSITION = -1; - - /** - * Return the current position of this tab in the action bar. - * - * @return Current position, or {@link #INVALID_POSITION} if this tab is not currently in - * the action bar. - */ - public abstract int getPosition(); - - /** - * Return the icon associated with this tab. - * - * @return The tab's icon - */ - public abstract Drawable getIcon(); - - /** - * Return the text of this tab. - * - * @return The tab's text - */ - public abstract CharSequence getText(); - - /** - * Set the icon displayed on this tab. - * - * @param icon The drawable to use as an icon - * @return The current instance for call chaining - */ - public abstract Tab setIcon(Drawable icon); - - /** - * Set the icon displayed on this tab. - * - * @param resId Resource ID referring to the drawable to use as an icon - * @return The current instance for call chaining - */ - public abstract Tab setIcon(int resId); - - /** - * Set the text displayed on this tab. Text may be truncated if there is not - * room to display the entire string. - * - * @param text The text to display - * @return The current instance for call chaining - */ - public abstract Tab setText(CharSequence text); - - /** - * Set the text displayed on this tab. Text may be truncated if there is not - * room to display the entire string. - * - * @param resId A resource ID referring to the text that should be displayed - * @return The current instance for call chaining - */ - public abstract Tab setText(int resId); - - /** - * Set a custom view to be used for this tab. This overrides values set by - * {@link #setText(CharSequence)} and {@link #setIcon(Drawable)}. - * - * @param view Custom view to be used as a tab. - * @return The current instance for call chaining - */ - public abstract Tab setCustomView(View view); - - /** - * Set a custom view to be used for this tab. This overrides values set by - * {@link #setText(CharSequence)} and {@link #setIcon(Drawable)}. - * - * @param layoutResId A layout resource to inflate and use as a custom tab view - * @return The current instance for call chaining - */ - public abstract Tab setCustomView(int layoutResId); - - /** - * Retrieve a previously set custom view for this tab. - * - * @return The custom view set by {@link #setCustomView(View)}. - */ - public abstract View getCustomView(); - - /** - * Give this Tab an arbitrary object to hold for later use. - * - * @param obj Object to store - * @return The current instance for call chaining - */ - public abstract Tab setTag(Object obj); - - /** - * @return This Tab's tag object. - */ - public abstract Object getTag(); - - /** - * Set the {@link TabListener} that will handle switching to and from this tab. - * All tabs must have a TabListener set before being added to the ActionBar. - * - * @param listener Listener to handle tab selection events - * @return The current instance for call chaining - */ - public abstract Tab setTabListener(TabListener listener); - - /** - * Select this tab. Only valid if the tab has been added to the action bar. - */ - public abstract void select(); - - /** - * Set a description of this tab's content for use in accessibility support. - * If no content description is provided the title will be used. - * - * @param resId A resource ID referring to the description text - * @return The current instance for call chaining - * @see #setContentDescription(CharSequence) - * @see #getContentDescription() - */ - public abstract Tab setContentDescription(int resId); - - /** - * Set a description of this tab's content for use in accessibility support. - * If no content description is provided the title will be used. - * - * @param contentDesc Description of this tab's content - * @return The current instance for call chaining - * @see #setContentDescription(int) - * @see #getContentDescription() - */ - public abstract Tab setContentDescription(CharSequence contentDesc); - - /** - * Gets a brief description of this tab's content for use in accessibility support. - * - * @return Description of this tab's content - * @see #setContentDescription(CharSequence) - * @see #setContentDescription(int) - */ - public abstract CharSequence getContentDescription(); - } - - /** - * Callback interface invoked when a tab is focused, unfocused, added, or removed. - */ - public interface TabListener { - /** - * Called when a tab enters the selected state. - * - * @param tab The tab that was selected - * @param ft A {@link FragmentTransaction} for queuing fragment operations to execute - * during a tab switch. The previous tab's unselect and this tab's select will be - * executed in a single transaction. This FragmentTransaction does not support - * being added to the back stack. - */ - public void onTabSelected(Tab tab, FragmentTransaction ft); - - /** - * Called when a tab exits the selected state. - * - * @param tab The tab that was unselected - * @param ft A {@link FragmentTransaction} for queuing fragment operations to execute - * during a tab switch. This tab's unselect and the newly selected tab's select - * will be executed in a single transaction. This FragmentTransaction does not - * support being added to the back stack. - */ - public void onTabUnselected(Tab tab, FragmentTransaction ft); - - /** - * Called when a tab that is already selected is chosen again by the user. - * Some applications may use this action to return to the top level of a category. - * - * @param tab The tab that was reselected. - * @param ft A {@link FragmentTransaction} for queuing fragment operations to execute - * once this method returns. This FragmentTransaction does not support - * being added to the back stack. - */ - public void onTabReselected(Tab tab, FragmentTransaction ft); - } - - /** - * Per-child layout information associated with action bar custom views. - * - * @attr ref android.R.styleable#ActionBar_LayoutParams_layout_gravity - */ - public static class LayoutParams extends MarginLayoutParams { - /** - * Gravity for the view associated with these LayoutParams. - * - * @see android.view.Gravity - */ - @ViewDebug.ExportedProperty(mapping = { - @ViewDebug.IntToString(from = -1, to = "NONE"), - @ViewDebug.IntToString(from = Gravity.NO_GRAVITY, to = "NONE"), - @ViewDebug.IntToString(from = Gravity.TOP, to = "TOP"), - @ViewDebug.IntToString(from = Gravity.BOTTOM, to = "BOTTOM"), - @ViewDebug.IntToString(from = Gravity.LEFT, to = "LEFT"), - @ViewDebug.IntToString(from = Gravity.RIGHT, to = "RIGHT"), - @ViewDebug.IntToString(from = Gravity.CENTER_VERTICAL, to = "CENTER_VERTICAL"), - @ViewDebug.IntToString(from = Gravity.FILL_VERTICAL, to = "FILL_VERTICAL"), - @ViewDebug.IntToString(from = Gravity.CENTER_HORIZONTAL, to = "CENTER_HORIZONTAL"), - @ViewDebug.IntToString(from = Gravity.FILL_HORIZONTAL, to = "FILL_HORIZONTAL"), - @ViewDebug.IntToString(from = Gravity.CENTER, to = "CENTER"), - @ViewDebug.IntToString(from = Gravity.FILL, to = "FILL") - }) - public int gravity = -1; - - public LayoutParams(Context c, AttributeSet attrs) { - super(c, attrs); - } - - public LayoutParams(int width, int height) { - super(width, height); - this.gravity = Gravity.CENTER_VERTICAL | Gravity.LEFT; - } - - public LayoutParams(int width, int height, int gravity) { - super(width, height); - this.gravity = gravity; - } - - public LayoutParams(int gravity) { - this(WRAP_CONTENT, FILL_PARENT, gravity); - } - - public LayoutParams(LayoutParams source) { - super(source); - - this.gravity = source.gravity; - } - - public LayoutParams(ViewGroup.LayoutParams source) { - super(source); - } - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/app/SherlockActivity.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/app/SherlockActivity.java deleted file mode 100644 index 9cb57e95a..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/app/SherlockActivity.java +++ /dev/null @@ -1,259 +0,0 @@ -package com.actionbarsherlock.app; - -import android.app.Activity; -import android.content.res.Configuration; -import android.os.Bundle; -import android.view.KeyEvent; -import android.view.View; -import android.view.Window; -import android.view.ViewGroup.LayoutParams; -import com.actionbarsherlock.ActionBarSherlock; -import com.actionbarsherlock.ActionBarSherlock.OnActionModeFinishedListener; -import com.actionbarsherlock.ActionBarSherlock.OnActionModeStartedListener; -import com.actionbarsherlock.ActionBarSherlock.OnCreatePanelMenuListener; -import com.actionbarsherlock.ActionBarSherlock.OnMenuItemSelectedListener; -import com.actionbarsherlock.ActionBarSherlock.OnPreparePanelListener; -import com.actionbarsherlock.view.ActionMode; -import com.actionbarsherlock.view.Menu; -import com.actionbarsherlock.view.MenuInflater; -import com.actionbarsherlock.view.MenuItem; - -public abstract class SherlockActivity extends Activity implements OnCreatePanelMenuListener, OnPreparePanelListener, OnMenuItemSelectedListener, OnActionModeStartedListener, OnActionModeFinishedListener { - private ActionBarSherlock mSherlock; - - protected final ActionBarSherlock getSherlock() { - if (mSherlock == null) { - mSherlock = ActionBarSherlock.wrap(this, ActionBarSherlock.FLAG_DELEGATE); - } - return mSherlock; - } - - - /////////////////////////////////////////////////////////////////////////// - // Action bar and mode - /////////////////////////////////////////////////////////////////////////// - - public ActionBar getSupportActionBar() { - return getSherlock().getActionBar(); - } - - public ActionMode startActionMode(ActionMode.Callback callback) { - return getSherlock().startActionMode(callback); - } - - @Override - public void onActionModeStarted(ActionMode mode) {} - - @Override - public void onActionModeFinished(ActionMode mode) {} - - - /////////////////////////////////////////////////////////////////////////// - // General lifecycle/callback dispatching - /////////////////////////////////////////////////////////////////////////// - - @Override - public void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - getSherlock().dispatchConfigurationChanged(newConfig); - } - - @Override - protected void onPostResume() { - super.onPostResume(); - getSherlock().dispatchPostResume(); - } - - @Override - protected void onPause() { - getSherlock().dispatchPause(); - super.onPause(); - } - - @Override - protected void onStop() { - getSherlock().dispatchStop(); - super.onStop(); - } - - @Override - protected void onDestroy() { - getSherlock().dispatchDestroy(); - super.onDestroy(); - } - - @Override - protected void onPostCreate(Bundle savedInstanceState) { - getSherlock().dispatchPostCreate(savedInstanceState); - super.onPostCreate(savedInstanceState); - } - - @Override - protected void onTitleChanged(CharSequence title, int color) { - getSherlock().dispatchTitleChanged(title, color); - super.onTitleChanged(title, color); - } - - @Override - public final boolean onMenuOpened(int featureId, android.view.Menu menu) { - if (getSherlock().dispatchMenuOpened(featureId, menu)) { - return true; - } - return super.onMenuOpened(featureId, menu); - } - - @Override - public void onPanelClosed(int featureId, android.view.Menu menu) { - getSherlock().dispatchPanelClosed(featureId, menu); - super.onPanelClosed(featureId, menu); - } - - @Override - public boolean dispatchKeyEvent(KeyEvent event) { - if (getSherlock().dispatchKeyEvent(event)) { - return true; - } - return super.dispatchKeyEvent(event); - } - - - /////////////////////////////////////////////////////////////////////////// - // Native menu handling - /////////////////////////////////////////////////////////////////////////// - - public MenuInflater getSupportMenuInflater() { - return getSherlock().getMenuInflater(); - } - - public void invalidateOptionsMenu() { - getSherlock().dispatchInvalidateOptionsMenu(); - } - - public void supportInvalidateOptionsMenu() { - invalidateOptionsMenu(); - } - - @Override - public final boolean onCreateOptionsMenu(android.view.Menu menu) { - return getSherlock().dispatchCreateOptionsMenu(menu); - } - - @Override - public final boolean onPrepareOptionsMenu(android.view.Menu menu) { - return getSherlock().dispatchPrepareOptionsMenu(menu); - } - - @Override - public final boolean onOptionsItemSelected(android.view.MenuItem item) { - return getSherlock().dispatchOptionsItemSelected(item); - } - - @Override - public void openOptionsMenu() { - if (!getSherlock().dispatchOpenOptionsMenu()) { - super.openOptionsMenu(); - } - } - - @Override - public void closeOptionsMenu() { - if (!getSherlock().dispatchCloseOptionsMenu()) { - super.closeOptionsMenu(); - } - } - - - /////////////////////////////////////////////////////////////////////////// - // Sherlock menu handling - /////////////////////////////////////////////////////////////////////////// - - @Override - public boolean onCreatePanelMenu(int featureId, Menu menu) { - if (featureId == Window.FEATURE_OPTIONS_PANEL) { - return onCreateOptionsMenu(menu); - } - return false; - } - - public boolean onCreateOptionsMenu(Menu menu) { - return true; - } - - @Override - public boolean onPreparePanel(int featureId, View view, Menu menu) { - if (featureId == Window.FEATURE_OPTIONS_PANEL) { - return onPrepareOptionsMenu(menu); - } - return false; - } - - public boolean onPrepareOptionsMenu(Menu menu) { - return true; - } - - @Override - public boolean onMenuItemSelected(int featureId, MenuItem item) { - if (featureId == Window.FEATURE_OPTIONS_PANEL) { - return onOptionsItemSelected(item); - } - return false; - } - - public boolean onOptionsItemSelected(MenuItem item) { - return false; - } - - - /////////////////////////////////////////////////////////////////////////// - // Content - /////////////////////////////////////////////////////////////////////////// - - @Override - public void addContentView(View view, LayoutParams params) { - getSherlock().addContentView(view, params); - } - - @Override - public void setContentView(int layoutResId) { - getSherlock().setContentView(layoutResId); - } - - @Override - public void setContentView(View view, LayoutParams params) { - getSherlock().setContentView(view, params); - } - - @Override - public void setContentView(View view) { - getSherlock().setContentView(view); - } - - public void requestWindowFeature(long featureId) { - getSherlock().requestFeature((int)featureId); - } - - - /////////////////////////////////////////////////////////////////////////// - // Progress Indication - /////////////////////////////////////////////////////////////////////////// - - public void setSupportProgress(int progress) { - getSherlock().setProgress(progress); - } - - public void setSupportProgressBarIndeterminate(boolean indeterminate) { - getSherlock().setProgressBarIndeterminate(indeterminate); - } - - public void setSupportProgressBarIndeterminateVisibility(boolean visible) { - getSherlock().setProgressBarIndeterminateVisibility(visible); - } - - public void setSupportProgressBarVisibility(boolean visible) { - getSherlock().setProgressBarVisibility(visible); - } - - public void setSupportSecondaryProgress(int secondaryProgress) { - getSherlock().setSecondaryProgress(secondaryProgress); - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/app/SherlockDialogFragment.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/app/SherlockDialogFragment.java deleted file mode 100644 index a7c856bf0..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/app/SherlockDialogFragment.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.actionbarsherlock.app; - -import android.app.Activity; -import android.support.v4.app.DialogFragment; -import com.actionbarsherlock.internal.view.menu.MenuItemWrapper; -import com.actionbarsherlock.internal.view.menu.MenuWrapper; -import com.actionbarsherlock.view.Menu; -import com.actionbarsherlock.view.MenuInflater; -import com.actionbarsherlock.view.MenuItem; - -import static com.actionbarsherlock.app.SherlockFragmentActivity.OnCreateOptionsMenuListener; -import static com.actionbarsherlock.app.SherlockFragmentActivity.OnOptionsItemSelectedListener; -import static com.actionbarsherlock.app.SherlockFragmentActivity.OnPrepareOptionsMenuListener; - -public class SherlockDialogFragment extends DialogFragment implements OnCreateOptionsMenuListener, OnPrepareOptionsMenuListener, OnOptionsItemSelectedListener { - private SherlockFragmentActivity mActivity; - - public SherlockFragmentActivity getSherlockActivity() { - return mActivity; - } - - @Override - public void onAttach(Activity activity) { - if (!(activity instanceof SherlockFragmentActivity)) { - throw new IllegalStateException(getClass().getSimpleName() + " must be attached to a SherlockFragmentActivity."); - } - mActivity = (SherlockFragmentActivity)activity; - - super.onAttach(activity); - } - - @Override - public void onDetach() { - mActivity = null; - super.onDetach(); - } - - @Override - public final void onCreateOptionsMenu(android.view.Menu menu, android.view.MenuInflater inflater) { - onCreateOptionsMenu(new MenuWrapper(menu), mActivity.getSupportMenuInflater()); - } - - @Override - public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { - //Nothing to see here. - } - - @Override - public final void onPrepareOptionsMenu(android.view.Menu menu) { - onPrepareOptionsMenu(new MenuWrapper(menu)); - } - - @Override - public void onPrepareOptionsMenu(Menu menu) { - //Nothing to see here. - } - - @Override - public final boolean onOptionsItemSelected(android.view.MenuItem item) { - return onOptionsItemSelected(new MenuItemWrapper(item)); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - //Nothing to see here. - return false; - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/app/SherlockExpandableListActivity.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/app/SherlockExpandableListActivity.java deleted file mode 100644 index 078f9b0ca..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/app/SherlockExpandableListActivity.java +++ /dev/null @@ -1,259 +0,0 @@ -package com.actionbarsherlock.app; - -import android.app.ExpandableListActivity; -import android.content.res.Configuration; -import android.os.Bundle; -import android.view.KeyEvent; -import android.view.View; -import android.view.ViewGroup.LayoutParams; -import android.view.Window; -import com.actionbarsherlock.ActionBarSherlock; -import com.actionbarsherlock.ActionBarSherlock.OnActionModeFinishedListener; -import com.actionbarsherlock.ActionBarSherlock.OnActionModeStartedListener; -import com.actionbarsherlock.ActionBarSherlock.OnCreatePanelMenuListener; -import com.actionbarsherlock.ActionBarSherlock.OnMenuItemSelectedListener; -import com.actionbarsherlock.ActionBarSherlock.OnPreparePanelListener; -import com.actionbarsherlock.view.ActionMode; -import com.actionbarsherlock.view.Menu; -import com.actionbarsherlock.view.MenuInflater; -import com.actionbarsherlock.view.MenuItem; - -public abstract class SherlockExpandableListActivity extends ExpandableListActivity implements OnCreatePanelMenuListener, OnPreparePanelListener, OnMenuItemSelectedListener, OnActionModeStartedListener, OnActionModeFinishedListener { - private ActionBarSherlock mSherlock; - - protected final ActionBarSherlock getSherlock() { - if (mSherlock == null) { - mSherlock = ActionBarSherlock.wrap(this, ActionBarSherlock.FLAG_DELEGATE); - } - return mSherlock; - } - - - /////////////////////////////////////////////////////////////////////////// - // Action bar and mode - /////////////////////////////////////////////////////////////////////////// - - public ActionBar getSupportActionBar() { - return getSherlock().getActionBar(); - } - - public ActionMode startActionMode(ActionMode.Callback callback) { - return getSherlock().startActionMode(callback); - } - - @Override - public void onActionModeStarted(ActionMode mode) {} - - @Override - public void onActionModeFinished(ActionMode mode) {} - - - /////////////////////////////////////////////////////////////////////////// - // General lifecycle/callback dispatching - /////////////////////////////////////////////////////////////////////////// - - @Override - public void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - getSherlock().dispatchConfigurationChanged(newConfig); - } - - @Override - protected void onPostResume() { - super.onPostResume(); - getSherlock().dispatchPostResume(); - } - - @Override - protected void onPause() { - getSherlock().dispatchPause(); - super.onPause(); - } - - @Override - protected void onStop() { - getSherlock().dispatchStop(); - super.onStop(); - } - - @Override - protected void onDestroy() { - getSherlock().dispatchDestroy(); - super.onDestroy(); - } - - @Override - protected void onPostCreate(Bundle savedInstanceState) { - getSherlock().dispatchPostCreate(savedInstanceState); - super.onPostCreate(savedInstanceState); - } - - @Override - protected void onTitleChanged(CharSequence title, int color) { - getSherlock().dispatchTitleChanged(title, color); - super.onTitleChanged(title, color); - } - - @Override - public final boolean onMenuOpened(int featureId, android.view.Menu menu) { - if (getSherlock().dispatchMenuOpened(featureId, menu)) { - return true; - } - return super.onMenuOpened(featureId, menu); - } - - @Override - public void onPanelClosed(int featureId, android.view.Menu menu) { - getSherlock().dispatchPanelClosed(featureId, menu); - super.onPanelClosed(featureId, menu); - } - - @Override - public boolean dispatchKeyEvent(KeyEvent event) { - if (getSherlock().dispatchKeyEvent(event)) { - return true; - } - return super.dispatchKeyEvent(event); - } - - - /////////////////////////////////////////////////////////////////////////// - // Native menu handling - /////////////////////////////////////////////////////////////////////////// - - public MenuInflater getSupportMenuInflater() { - return getSherlock().getMenuInflater(); - } - - public void invalidateOptionsMenu() { - getSherlock().dispatchInvalidateOptionsMenu(); - } - - public void supportInvalidateOptionsMenu() { - invalidateOptionsMenu(); - } - - @Override - public final boolean onCreateOptionsMenu(android.view.Menu menu) { - return getSherlock().dispatchCreateOptionsMenu(menu); - } - - @Override - public final boolean onPrepareOptionsMenu(android.view.Menu menu) { - return getSherlock().dispatchPrepareOptionsMenu(menu); - } - - @Override - public final boolean onOptionsItemSelected(android.view.MenuItem item) { - return getSherlock().dispatchOptionsItemSelected(item); - } - - @Override - public void openOptionsMenu() { - if (!getSherlock().dispatchOpenOptionsMenu()) { - super.openOptionsMenu(); - } - } - - @Override - public void closeOptionsMenu() { - if (!getSherlock().dispatchCloseOptionsMenu()) { - super.closeOptionsMenu(); - } - } - - - /////////////////////////////////////////////////////////////////////////// - // Sherlock menu handling - /////////////////////////////////////////////////////////////////////////// - - @Override - public boolean onCreatePanelMenu(int featureId, Menu menu) { - if (featureId == Window.FEATURE_OPTIONS_PANEL) { - return onCreateOptionsMenu(menu); - } - return false; - } - - public boolean onCreateOptionsMenu(Menu menu) { - return true; - } - - @Override - public boolean onPreparePanel(int featureId, View view, Menu menu) { - if (featureId == Window.FEATURE_OPTIONS_PANEL) { - return onPrepareOptionsMenu(menu); - } - return false; - } - - public boolean onPrepareOptionsMenu(Menu menu) { - return true; - } - - @Override - public boolean onMenuItemSelected(int featureId, MenuItem item) { - if (featureId == Window.FEATURE_OPTIONS_PANEL) { - return onOptionsItemSelected(item); - } - return false; - } - - public boolean onOptionsItemSelected(MenuItem item) { - return false; - } - - - /////////////////////////////////////////////////////////////////////////// - // Content - /////////////////////////////////////////////////////////////////////////// - - @Override - public void addContentView(View view, LayoutParams params) { - getSherlock().addContentView(view, params); - } - - @Override - public void setContentView(int layoutResId) { - getSherlock().setContentView(layoutResId); - } - - @Override - public void setContentView(View view, LayoutParams params) { - getSherlock().setContentView(view, params); - } - - @Override - public void setContentView(View view) { - getSherlock().setContentView(view); - } - - public void requestWindowFeature(long featureId) { - getSherlock().requestFeature((int)featureId); - } - - - /////////////////////////////////////////////////////////////////////////// - // Progress Indication - /////////////////////////////////////////////////////////////////////////// - - public void setSupportProgress(int progress) { - getSherlock().setProgress(progress); - } - - public void setSupportProgressBarIndeterminate(boolean indeterminate) { - getSherlock().setProgressBarIndeterminate(indeterminate); - } - - public void setSupportProgressBarIndeterminateVisibility(boolean visible) { - getSherlock().setProgressBarIndeterminateVisibility(visible); - } - - public void setSupportProgressBarVisibility(boolean visible) { - getSherlock().setProgressBarVisibility(visible); - } - - public void setSupportSecondaryProgress(int secondaryProgress) { - getSherlock().setSecondaryProgress(secondaryProgress); - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/app/SherlockFragment.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/app/SherlockFragment.java deleted file mode 100644 index 0f24e9c85..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/app/SherlockFragment.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.actionbarsherlock.app; - -import android.app.Activity; -import android.support.v4.app.Fragment; -import com.actionbarsherlock.internal.view.menu.MenuItemWrapper; -import com.actionbarsherlock.internal.view.menu.MenuWrapper; -import com.actionbarsherlock.view.Menu; -import com.actionbarsherlock.view.MenuInflater; -import com.actionbarsherlock.view.MenuItem; - -import static com.actionbarsherlock.app.SherlockFragmentActivity.OnCreateOptionsMenuListener; -import static com.actionbarsherlock.app.SherlockFragmentActivity.OnOptionsItemSelectedListener; -import static com.actionbarsherlock.app.SherlockFragmentActivity.OnPrepareOptionsMenuListener; - -public class SherlockFragment extends Fragment implements OnCreateOptionsMenuListener, OnPrepareOptionsMenuListener, OnOptionsItemSelectedListener { - private SherlockFragmentActivity mActivity; - - public SherlockFragmentActivity getSherlockActivity() { - return mActivity; - } - - @Override - public void onAttach(Activity activity) { - if (!(activity instanceof SherlockFragmentActivity)) { - throw new IllegalStateException(getClass().getSimpleName() + " must be attached to a SherlockFragmentActivity."); - } - mActivity = (SherlockFragmentActivity)activity; - - super.onAttach(activity); - } - - @Override - public void onDetach() { - mActivity = null; - super.onDetach(); - } - - @Override - public final void onCreateOptionsMenu(android.view.Menu menu, android.view.MenuInflater inflater) { - onCreateOptionsMenu(new MenuWrapper(menu), mActivity.getSupportMenuInflater()); - } - - @Override - public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { - //Nothing to see here. - } - - @Override - public final void onPrepareOptionsMenu(android.view.Menu menu) { - onPrepareOptionsMenu(new MenuWrapper(menu)); - } - - @Override - public void onPrepareOptionsMenu(Menu menu) { - //Nothing to see here. - } - - @Override - public final boolean onOptionsItemSelected(android.view.MenuItem item) { - return onOptionsItemSelected(new MenuItemWrapper(item)); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - //Nothing to see here. - return false; - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/app/SherlockFragmentActivity.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/app/SherlockFragmentActivity.java deleted file mode 100644 index 5cd13ba7c..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/app/SherlockFragmentActivity.java +++ /dev/null @@ -1,292 +0,0 @@ -package com.actionbarsherlock.app; - -import android.content.res.Configuration; -import android.os.Bundle; -import android.support.v4.app._ActionBarSherlockTrojanHorse; -import android.util.Log; -import android.view.KeyEvent; -import android.view.View; -import android.view.ViewGroup.LayoutParams; -import android.view.Window; -import com.actionbarsherlock.ActionBarSherlock; -import com.actionbarsherlock.view.ActionMode; -import com.actionbarsherlock.view.Menu; -import com.actionbarsherlock.view.MenuInflater; -import com.actionbarsherlock.view.MenuItem; - -import static com.actionbarsherlock.ActionBarSherlock.OnActionModeFinishedListener; -import static com.actionbarsherlock.ActionBarSherlock.OnActionModeStartedListener; - -/** @see {@link _ActionBarSherlockTrojanHorse} */ -public class SherlockFragmentActivity extends _ActionBarSherlockTrojanHorse implements OnActionModeStartedListener, OnActionModeFinishedListener { - private static final boolean DEBUG = false; - private static final String TAG = "SherlockFragmentActivity"; - - private ActionBarSherlock mSherlock; - private boolean mIgnoreNativeCreate = false; - private boolean mIgnoreNativePrepare = false; - private boolean mIgnoreNativeSelected = false; - - protected final ActionBarSherlock getSherlock() { - if (mSherlock == null) { - mSherlock = ActionBarSherlock.wrap(this, ActionBarSherlock.FLAG_DELEGATE); - } - return mSherlock; - } - - - /////////////////////////////////////////////////////////////////////////// - // Action bar and mode - /////////////////////////////////////////////////////////////////////////// - - public ActionBar getSupportActionBar() { - return getSherlock().getActionBar(); - } - - public ActionMode startActionMode(ActionMode.Callback callback) { - return getSherlock().startActionMode(callback); - } - - @Override - public void onActionModeStarted(ActionMode mode) {} - - @Override - public void onActionModeFinished(ActionMode mode) {} - - - /////////////////////////////////////////////////////////////////////////// - // General lifecycle/callback dispatching - /////////////////////////////////////////////////////////////////////////// - - @Override - public void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - getSherlock().dispatchConfigurationChanged(newConfig); - } - - @Override - protected void onPostResume() { - super.onPostResume(); - getSherlock().dispatchPostResume(); - } - - @Override - protected void onPause() { - getSherlock().dispatchPause(); - super.onPause(); - } - - @Override - protected void onStop() { - getSherlock().dispatchStop(); - super.onStop(); - } - - @Override - protected void onDestroy() { - getSherlock().dispatchDestroy(); - super.onDestroy(); - } - - @Override - protected void onPostCreate(Bundle savedInstanceState) { - getSherlock().dispatchPostCreate(savedInstanceState); - super.onPostCreate(savedInstanceState); - } - - @Override - protected void onTitleChanged(CharSequence title, int color) { - getSherlock().dispatchTitleChanged(title, color); - super.onTitleChanged(title, color); - } - - @Override - public final boolean onMenuOpened(int featureId, android.view.Menu menu) { - if (getSherlock().dispatchMenuOpened(featureId, menu)) { - return true; - } - return super.onMenuOpened(featureId, menu); - } - - @Override - public void onPanelClosed(int featureId, android.view.Menu menu) { - getSherlock().dispatchPanelClosed(featureId, menu); - super.onPanelClosed(featureId, menu); - } - - @Override - public boolean dispatchKeyEvent(KeyEvent event) { - if (getSherlock().dispatchKeyEvent(event)) { - return true; - } - return super.dispatchKeyEvent(event); - } - - - /////////////////////////////////////////////////////////////////////////// - // Native menu handling - /////////////////////////////////////////////////////////////////////////// - - public MenuInflater getSupportMenuInflater() { - if (DEBUG) Log.d(TAG, "[getSupportMenuInflater]"); - - return getSherlock().getMenuInflater(); - } - - public void invalidateOptionsMenu() { - if (DEBUG) Log.d(TAG, "[invalidateOptionsMenu]"); - - getSherlock().dispatchInvalidateOptionsMenu(); - } - - public void supportInvalidateOptionsMenu() { - if (DEBUG) Log.d(TAG, "[supportInvalidateOptionsMenu]"); - - invalidateOptionsMenu(); - } - - @Override - public final boolean onCreatePanelMenu(int featureId, android.view.Menu menu) { - if (DEBUG) Log.d(TAG, "[onCreatePanelMenu] featureId: " + featureId + ", menu: " + menu); - - if (featureId == Window.FEATURE_OPTIONS_PANEL && !mIgnoreNativeCreate) { - mIgnoreNativeCreate = true; - boolean result = getSherlock().dispatchCreateOptionsMenu(menu); - mIgnoreNativeCreate = false; - - if (DEBUG) Log.d(TAG, "[onCreatePanelMenu] returning " + result); - return result; - } - return super.onCreatePanelMenu(featureId, menu); - } - - @Override - public final boolean onCreateOptionsMenu(android.view.Menu menu) { - return true; - } - - @Override - public final boolean onPreparePanel(int featureId, View view, android.view.Menu menu) { - if (DEBUG) Log.d(TAG, "[onPreparePanel] featureId: " + featureId + ", view: " + view + ", menu: " + menu); - - if (featureId == Window.FEATURE_OPTIONS_PANEL && !mIgnoreNativePrepare) { - mIgnoreNativePrepare = true; - boolean result = getSherlock().dispatchPrepareOptionsMenu(menu); - mIgnoreNativePrepare = false; - - if (DEBUG) Log.d(TAG, "[onPreparePanel] returning " + result); - return result; - } - return super.onPreparePanel(featureId, view, menu); - } - - @Override - public final boolean onPrepareOptionsMenu(android.view.Menu menu) { - return true; - } - - @Override - public final boolean onMenuItemSelected(int featureId, android.view.MenuItem item) { - if (DEBUG) Log.d(TAG, "[onMenuItemSelected] featureId: " + featureId + ", item: " + item); - - if (featureId == Window.FEATURE_OPTIONS_PANEL && !mIgnoreNativeSelected) { - mIgnoreNativeSelected = true; - boolean result = getSherlock().dispatchOptionsItemSelected(item); - mIgnoreNativeSelected = false; - - if (DEBUG) Log.d(TAG, "[onMenuItemSelected] returning " + result); - return result; - } - return super.onMenuItemSelected(featureId, item); - } - - @Override - public final boolean onOptionsItemSelected(android.view.MenuItem item) { - return false; - } - - @Override - public void openOptionsMenu() { - if (!getSherlock().dispatchOpenOptionsMenu()) { - super.openOptionsMenu(); - } - } - - @Override - public void closeOptionsMenu() { - if (!getSherlock().dispatchCloseOptionsMenu()) { - super.closeOptionsMenu(); - } - } - - - /////////////////////////////////////////////////////////////////////////// - // Sherlock menu handling - /////////////////////////////////////////////////////////////////////////// - - public boolean onCreateOptionsMenu(Menu menu) { - return true; - } - - public boolean onPrepareOptionsMenu(Menu menu) { - return true; - } - - public boolean onOptionsItemSelected(MenuItem item) { - return false; - } - - - /////////////////////////////////////////////////////////////////////////// - // Content - /////////////////////////////////////////////////////////////////////////// - - @Override - public void addContentView(View view, LayoutParams params) { - getSherlock().addContentView(view, params); - } - - @Override - public void setContentView(int layoutResId) { - getSherlock().setContentView(layoutResId); - } - - @Override - public void setContentView(View view, LayoutParams params) { - getSherlock().setContentView(view, params); - } - - @Override - public void setContentView(View view) { - getSherlock().setContentView(view); - } - - public void requestWindowFeature(long featureId) { - getSherlock().requestFeature((int)featureId); - } - - - /////////////////////////////////////////////////////////////////////////// - // Progress Indication - /////////////////////////////////////////////////////////////////////////// - - public void setSupportProgress(int progress) { - getSherlock().setProgress(progress); - } - - public void setSupportProgressBarIndeterminate(boolean indeterminate) { - getSherlock().setProgressBarIndeterminate(indeterminate); - } - - public void setSupportProgressBarIndeterminateVisibility(boolean visible) { - getSherlock().setProgressBarIndeterminateVisibility(visible); - } - - public void setSupportProgressBarVisibility(boolean visible) { - getSherlock().setProgressBarVisibility(visible); - } - - public void setSupportSecondaryProgress(int secondaryProgress) { - getSherlock().setSecondaryProgress(secondaryProgress); - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/app/SherlockListActivity.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/app/SherlockListActivity.java deleted file mode 100644 index 00c00fee5..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/app/SherlockListActivity.java +++ /dev/null @@ -1,259 +0,0 @@ -package com.actionbarsherlock.app; - -import android.app.ListActivity; -import android.content.res.Configuration; -import android.os.Bundle; -import android.view.KeyEvent; -import android.view.View; -import android.view.Window; -import android.view.ViewGroup.LayoutParams; -import com.actionbarsherlock.ActionBarSherlock; -import com.actionbarsherlock.ActionBarSherlock.OnActionModeFinishedListener; -import com.actionbarsherlock.ActionBarSherlock.OnActionModeStartedListener; -import com.actionbarsherlock.ActionBarSherlock.OnCreatePanelMenuListener; -import com.actionbarsherlock.ActionBarSherlock.OnMenuItemSelectedListener; -import com.actionbarsherlock.ActionBarSherlock.OnPreparePanelListener; -import com.actionbarsherlock.view.ActionMode; -import com.actionbarsherlock.view.Menu; -import com.actionbarsherlock.view.MenuInflater; -import com.actionbarsherlock.view.MenuItem; - -public abstract class SherlockListActivity extends ListActivity implements OnCreatePanelMenuListener, OnPreparePanelListener, OnMenuItemSelectedListener, OnActionModeStartedListener, OnActionModeFinishedListener { - private ActionBarSherlock mSherlock; - - protected final ActionBarSherlock getSherlock() { - if (mSherlock == null) { - mSherlock = ActionBarSherlock.wrap(this, ActionBarSherlock.FLAG_DELEGATE); - } - return mSherlock; - } - - - /////////////////////////////////////////////////////////////////////////// - // Action bar and mode - /////////////////////////////////////////////////////////////////////////// - - public ActionBar getSupportActionBar() { - return getSherlock().getActionBar(); - } - - public ActionMode startActionMode(ActionMode.Callback callback) { - return getSherlock().startActionMode(callback); - } - - @Override - public void onActionModeStarted(ActionMode mode) {} - - @Override - public void onActionModeFinished(ActionMode mode) {} - - - /////////////////////////////////////////////////////////////////////////// - // General lifecycle/callback dispatching - /////////////////////////////////////////////////////////////////////////// - - @Override - public void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - getSherlock().dispatchConfigurationChanged(newConfig); - } - - @Override - protected void onPostResume() { - super.onPostResume(); - getSherlock().dispatchPostResume(); - } - - @Override - protected void onPause() { - getSherlock().dispatchPause(); - super.onPause(); - } - - @Override - protected void onStop() { - getSherlock().dispatchStop(); - super.onStop(); - } - - @Override - protected void onDestroy() { - getSherlock().dispatchDestroy(); - super.onDestroy(); - } - - @Override - protected void onPostCreate(Bundle savedInstanceState) { - getSherlock().dispatchPostCreate(savedInstanceState); - super.onPostCreate(savedInstanceState); - } - - @Override - protected void onTitleChanged(CharSequence title, int color) { - getSherlock().dispatchTitleChanged(title, color); - super.onTitleChanged(title, color); - } - - @Override - public final boolean onMenuOpened(int featureId, android.view.Menu menu) { - if (getSherlock().dispatchMenuOpened(featureId, menu)) { - return true; - } - return super.onMenuOpened(featureId, menu); - } - - @Override - public void onPanelClosed(int featureId, android.view.Menu menu) { - getSherlock().dispatchPanelClosed(featureId, menu); - super.onPanelClosed(featureId, menu); - } - - @Override - public boolean dispatchKeyEvent(KeyEvent event) { - if (getSherlock().dispatchKeyEvent(event)) { - return true; - } - return super.dispatchKeyEvent(event); - } - - - /////////////////////////////////////////////////////////////////////////// - // Native menu handling - /////////////////////////////////////////////////////////////////////////// - - public MenuInflater getSupportMenuInflater() { - return getSherlock().getMenuInflater(); - } - - public void invalidateOptionsMenu() { - getSherlock().dispatchInvalidateOptionsMenu(); - } - - public void supportInvalidateOptionsMenu() { - invalidateOptionsMenu(); - } - - @Override - public final boolean onCreateOptionsMenu(android.view.Menu menu) { - return getSherlock().dispatchCreateOptionsMenu(menu); - } - - @Override - public final boolean onPrepareOptionsMenu(android.view.Menu menu) { - return getSherlock().dispatchPrepareOptionsMenu(menu); - } - - @Override - public final boolean onOptionsItemSelected(android.view.MenuItem item) { - return getSherlock().dispatchOptionsItemSelected(item); - } - - @Override - public void openOptionsMenu() { - if (!getSherlock().dispatchOpenOptionsMenu()) { - super.openOptionsMenu(); - } - } - - @Override - public void closeOptionsMenu() { - if (!getSherlock().dispatchCloseOptionsMenu()) { - super.closeOptionsMenu(); - } - } - - - /////////////////////////////////////////////////////////////////////////// - // Sherlock menu handling - /////////////////////////////////////////////////////////////////////////// - - @Override - public boolean onCreatePanelMenu(int featureId, Menu menu) { - if (featureId == Window.FEATURE_OPTIONS_PANEL) { - return onCreateOptionsMenu(menu); - } - return false; - } - - public boolean onCreateOptionsMenu(Menu menu) { - return true; - } - - @Override - public boolean onPreparePanel(int featureId, View view, Menu menu) { - if (featureId == Window.FEATURE_OPTIONS_PANEL) { - return onPrepareOptionsMenu(menu); - } - return false; - } - - public boolean onPrepareOptionsMenu(Menu menu) { - return true; - } - - @Override - public boolean onMenuItemSelected(int featureId, MenuItem item) { - if (featureId == Window.FEATURE_OPTIONS_PANEL) { - return onOptionsItemSelected(item); - } - return false; - } - - public boolean onOptionsItemSelected(MenuItem item) { - return false; - } - - - /////////////////////////////////////////////////////////////////////////// - // Content - /////////////////////////////////////////////////////////////////////////// - - @Override - public void addContentView(View view, LayoutParams params) { - getSherlock().addContentView(view, params); - } - - @Override - public void setContentView(int layoutResId) { - getSherlock().setContentView(layoutResId); - } - - @Override - public void setContentView(View view, LayoutParams params) { - getSherlock().setContentView(view, params); - } - - @Override - public void setContentView(View view) { - getSherlock().setContentView(view); - } - - public void requestWindowFeature(long featureId) { - getSherlock().requestFeature((int)featureId); - } - - - /////////////////////////////////////////////////////////////////////////// - // Progress Indication - /////////////////////////////////////////////////////////////////////////// - - public void setSupportProgress(int progress) { - getSherlock().setProgress(progress); - } - - public void setSupportProgressBarIndeterminate(boolean indeterminate) { - getSherlock().setProgressBarIndeterminate(indeterminate); - } - - public void setSupportProgressBarIndeterminateVisibility(boolean visible) { - getSherlock().setProgressBarIndeterminateVisibility(visible); - } - - public void setSupportProgressBarVisibility(boolean visible) { - getSherlock().setProgressBarVisibility(visible); - } - - public void setSupportSecondaryProgress(int secondaryProgress) { - getSherlock().setSecondaryProgress(secondaryProgress); - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/app/SherlockListFragment.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/app/SherlockListFragment.java deleted file mode 100644 index 13ca3c49f..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/app/SherlockListFragment.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.actionbarsherlock.app; - -import android.app.Activity; -import android.support.v4.app.ListFragment; -import com.actionbarsherlock.internal.view.menu.MenuItemWrapper; -import com.actionbarsherlock.internal.view.menu.MenuWrapper; -import com.actionbarsherlock.view.Menu; -import com.actionbarsherlock.view.MenuInflater; -import com.actionbarsherlock.view.MenuItem; - -import static com.actionbarsherlock.app.SherlockFragmentActivity.OnCreateOptionsMenuListener; -import static com.actionbarsherlock.app.SherlockFragmentActivity.OnOptionsItemSelectedListener; -import static com.actionbarsherlock.app.SherlockFragmentActivity.OnPrepareOptionsMenuListener; - -public class SherlockListFragment extends ListFragment implements OnCreateOptionsMenuListener, OnPrepareOptionsMenuListener, OnOptionsItemSelectedListener { - private SherlockFragmentActivity mActivity; - - public SherlockFragmentActivity getSherlockActivity() { - return mActivity; - } - - @Override - public void onAttach(Activity activity) { - if (!(activity instanceof SherlockFragmentActivity)) { - throw new IllegalStateException(getClass().getSimpleName() + " must be attached to a SherlockFragmentActivity."); - } - mActivity = (SherlockFragmentActivity)activity; - - super.onAttach(activity); - } - - @Override - public void onDetach() { - mActivity = null; - super.onDetach(); - } - - @Override - public final void onCreateOptionsMenu(android.view.Menu menu, android.view.MenuInflater inflater) { - onCreateOptionsMenu(new MenuWrapper(menu), mActivity.getSupportMenuInflater()); - } - - @Override - public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { - //Nothing to see here. - } - - @Override - public final void onPrepareOptionsMenu(android.view.Menu menu) { - onPrepareOptionsMenu(new MenuWrapper(menu)); - } - - @Override - public void onPrepareOptionsMenu(Menu menu) { - //Nothing to see here. - } - - @Override - public final boolean onOptionsItemSelected(android.view.MenuItem item) { - return onOptionsItemSelected(new MenuItemWrapper(item)); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - //Nothing to see here. - return false; - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/app/SherlockPreferenceActivity.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/app/SherlockPreferenceActivity.java deleted file mode 100644 index 4f80be515..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/app/SherlockPreferenceActivity.java +++ /dev/null @@ -1,259 +0,0 @@ -package com.actionbarsherlock.app; - -import android.content.res.Configuration; -import android.os.Bundle; -import android.preference.PreferenceActivity; -import android.view.KeyEvent; -import android.view.View; -import android.view.ViewGroup.LayoutParams; -import android.view.Window; -import com.actionbarsherlock.ActionBarSherlock; -import com.actionbarsherlock.ActionBarSherlock.OnActionModeFinishedListener; -import com.actionbarsherlock.ActionBarSherlock.OnActionModeStartedListener; -import com.actionbarsherlock.ActionBarSherlock.OnCreatePanelMenuListener; -import com.actionbarsherlock.ActionBarSherlock.OnMenuItemSelectedListener; -import com.actionbarsherlock.ActionBarSherlock.OnPreparePanelListener; -import com.actionbarsherlock.view.ActionMode; -import com.actionbarsherlock.view.Menu; -import com.actionbarsherlock.view.MenuInflater; -import com.actionbarsherlock.view.MenuItem; - -public abstract class SherlockPreferenceActivity extends PreferenceActivity implements OnCreatePanelMenuListener, OnPreparePanelListener, OnMenuItemSelectedListener, OnActionModeStartedListener, OnActionModeFinishedListener { - private ActionBarSherlock mSherlock; - - protected final ActionBarSherlock getSherlock() { - if (mSherlock == null) { - mSherlock = ActionBarSherlock.wrap(this, ActionBarSherlock.FLAG_DELEGATE); - } - return mSherlock; - } - - - /////////////////////////////////////////////////////////////////////////// - // Action bar and mode - /////////////////////////////////////////////////////////////////////////// - - public ActionBar getSupportActionBar() { - return getSherlock().getActionBar(); - } - - public ActionMode startActionMode(ActionMode.Callback callback) { - return getSherlock().startActionMode(callback); - } - - @Override - public void onActionModeStarted(ActionMode mode) {} - - @Override - public void onActionModeFinished(ActionMode mode) {} - - - /////////////////////////////////////////////////////////////////////////// - // General lifecycle/callback dispatching - /////////////////////////////////////////////////////////////////////////// - - @Override - public void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - getSherlock().dispatchConfigurationChanged(newConfig); - } - - @Override - protected void onPostResume() { - super.onPostResume(); - getSherlock().dispatchPostResume(); - } - - @Override - protected void onPause() { - getSherlock().dispatchPause(); - super.onPause(); - } - - @Override - protected void onStop() { - getSherlock().dispatchStop(); - super.onStop(); - } - - @Override - protected void onDestroy() { - getSherlock().dispatchDestroy(); - super.onDestroy(); - } - - @Override - protected void onPostCreate(Bundle savedInstanceState) { - getSherlock().dispatchPostCreate(savedInstanceState); - super.onPostCreate(savedInstanceState); - } - - @Override - protected void onTitleChanged(CharSequence title, int color) { - getSherlock().dispatchTitleChanged(title, color); - super.onTitleChanged(title, color); - } - - @Override - public final boolean onMenuOpened(int featureId, android.view.Menu menu) { - if (getSherlock().dispatchMenuOpened(featureId, menu)) { - return true; - } - return super.onMenuOpened(featureId, menu); - } - - @Override - public void onPanelClosed(int featureId, android.view.Menu menu) { - getSherlock().dispatchPanelClosed(featureId, menu); - super.onPanelClosed(featureId, menu); - } - - @Override - public boolean dispatchKeyEvent(KeyEvent event) { - if (getSherlock().dispatchKeyEvent(event)) { - return true; - } - return super.dispatchKeyEvent(event); - } - - - /////////////////////////////////////////////////////////////////////////// - // Native menu handling - /////////////////////////////////////////////////////////////////////////// - - public MenuInflater getSupportMenuInflater() { - return getSherlock().getMenuInflater(); - } - - public void invalidateOptionsMenu() { - getSherlock().dispatchInvalidateOptionsMenu(); - } - - public void supportInvalidateOptionsMenu() { - invalidateOptionsMenu(); - } - - @Override - public final boolean onCreateOptionsMenu(android.view.Menu menu) { - return getSherlock().dispatchCreateOptionsMenu(menu); - } - - @Override - public final boolean onPrepareOptionsMenu(android.view.Menu menu) { - return getSherlock().dispatchPrepareOptionsMenu(menu); - } - - @Override - public final boolean onOptionsItemSelected(android.view.MenuItem item) { - return getSherlock().dispatchOptionsItemSelected(item); - } - - @Override - public void openOptionsMenu() { - if (!getSherlock().dispatchOpenOptionsMenu()) { - super.openOptionsMenu(); - } - } - - @Override - public void closeOptionsMenu() { - if (!getSherlock().dispatchCloseOptionsMenu()) { - super.closeOptionsMenu(); - } - } - - - /////////////////////////////////////////////////////////////////////////// - // Sherlock menu handling - /////////////////////////////////////////////////////////////////////////// - - @Override - public boolean onCreatePanelMenu(int featureId, Menu menu) { - if (featureId == Window.FEATURE_OPTIONS_PANEL) { - return onCreateOptionsMenu(menu); - } - return false; - } - - public boolean onCreateOptionsMenu(Menu menu) { - return true; - } - - @Override - public boolean onPreparePanel(int featureId, View view, Menu menu) { - if (featureId == Window.FEATURE_OPTIONS_PANEL) { - return onPrepareOptionsMenu(menu); - } - return false; - } - - public boolean onPrepareOptionsMenu(Menu menu) { - return true; - } - - @Override - public boolean onMenuItemSelected(int featureId, MenuItem item) { - if (featureId == Window.FEATURE_OPTIONS_PANEL) { - return onOptionsItemSelected(item); - } - return false; - } - - public boolean onOptionsItemSelected(MenuItem item) { - return false; - } - - - /////////////////////////////////////////////////////////////////////////// - // Content - /////////////////////////////////////////////////////////////////////////// - - @Override - public void addContentView(View view, LayoutParams params) { - getSherlock().addContentView(view, params); - } - - @Override - public void setContentView(int layoutResId) { - getSherlock().setContentView(layoutResId); - } - - @Override - public void setContentView(View view, LayoutParams params) { - getSherlock().setContentView(view, params); - } - - @Override - public void setContentView(View view) { - getSherlock().setContentView(view); - } - - public void requestWindowFeature(long featureId) { - getSherlock().requestFeature((int)featureId); - } - - - /////////////////////////////////////////////////////////////////////////// - // Progress Indication - /////////////////////////////////////////////////////////////////////////// - - public void setSupportProgress(int progress) { - getSherlock().setProgress(progress); - } - - public void setSupportProgressBarIndeterminate(boolean indeterminate) { - getSherlock().setProgressBarIndeterminate(indeterminate); - } - - public void setSupportProgressBarIndeterminateVisibility(boolean visible) { - getSherlock().setProgressBarIndeterminateVisibility(visible); - } - - public void setSupportProgressBarVisibility(boolean visible) { - getSherlock().setProgressBarVisibility(visible); - } - - public void setSupportSecondaryProgress(int secondaryProgress) { - getSherlock().setSecondaryProgress(secondaryProgress); - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/ActionBarSherlockCompat.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/ActionBarSherlockCompat.java deleted file mode 100644 index 05353d28c..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/ActionBarSherlockCompat.java +++ /dev/null @@ -1,1207 +0,0 @@ -package com.actionbarsherlock.internal; - -import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; -import static com.actionbarsherlock.internal.ResourcesCompat.getResources_getBoolean; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import org.xmlpull.v1.XmlPullParser; -import android.app.Activity; -import android.content.Context; -import android.content.pm.ActivityInfo; -import android.content.res.AssetManager; -import android.content.res.Configuration; -import android.content.res.Resources; -import android.content.res.TypedArray; -import android.content.res.XmlResourceParser; -import android.os.Bundle; -import android.util.AndroidRuntimeException; -import android.util.Log; -import android.util.TypedValue; -import android.view.ContextThemeWrapper; -import android.view.KeyCharacterMap; -import android.view.KeyEvent; -import android.view.View; -import android.view.ViewGroup; -import android.view.ViewStub; -import android.view.Window; -import android.view.accessibility.AccessibilityEvent; -import android.view.animation.Animation; -import android.view.animation.AnimationUtils; -import android.widget.FrameLayout; -import android.widget.TextView; -import com.actionbarsherlock.ActionBarSherlock; -import com.actionbarsherlock.R; -import com.actionbarsherlock.app.ActionBar; -import com.actionbarsherlock.internal.app.ActionBarImpl; -import com.actionbarsherlock.internal.view.StandaloneActionMode; -import com.actionbarsherlock.internal.view.menu.ActionMenuPresenter; -import com.actionbarsherlock.internal.view.menu.MenuBuilder; -import com.actionbarsherlock.internal.view.menu.MenuItemImpl; -import com.actionbarsherlock.internal.view.menu.MenuPresenter; -import com.actionbarsherlock.internal.widget.ActionBarContainer; -import com.actionbarsherlock.internal.widget.ActionBarContextView; -import com.actionbarsherlock.internal.widget.ActionBarView; -import com.actionbarsherlock.internal.widget.IcsProgressBar; -import com.actionbarsherlock.view.ActionMode; -import com.actionbarsherlock.view.Menu; -import com.actionbarsherlock.view.MenuItem; - -@ActionBarSherlock.Implementation(api = 7) -public class ActionBarSherlockCompat extends ActionBarSherlock implements MenuBuilder.Callback, com.actionbarsherlock.view.Window.Callback, MenuPresenter.Callback, android.view.MenuItem.OnMenuItemClickListener { - /** Window features which are enabled by default. */ - protected static final int DEFAULT_FEATURES = 0; - - - public ActionBarSherlockCompat(Activity activity, int flags) { - super(activity, flags); - } - - - /////////////////////////////////////////////////////////////////////////// - // Properties - /////////////////////////////////////////////////////////////////////////// - - /** Whether or not the device has a dedicated menu key button. */ - private boolean mReserveOverflow; - /** Lazy-load indicator for {@link #mReserveOverflow}. */ - private boolean mReserveOverflowSet = false; - - /** Current menu instance for managing action items. */ - private MenuBuilder mMenu; - /** Map between native options items and sherlock items. */ - protected HashMap mNativeItemMap; - /** Indication of a long-press on the hardware menu key. */ - private boolean mMenuKeyIsLongPress = false; - - /** Parent view of the window decoration (action bar, mode, etc.). */ - private ViewGroup mDecor; - /** Parent view of the activity content. */ - private ViewGroup mContentParent; - - /** Whether or not the title is stable and can be displayed. */ - private boolean mIsTitleReady = false; - /** Whether or not the parent activity has been destroyed. */ - private boolean mIsDestroyed = false; - - /* Emulate PanelFeatureState */ - private boolean mClosingActionMenu; - private boolean mMenuIsPrepared; - private boolean mMenuRefreshContent; - private Bundle mMenuFrozenActionViewState; - - /** Implementation which backs the action bar interface API. */ - private ActionBarImpl aActionBar; - /** Main action bar view which displays the core content. */ - private ActionBarView wActionBar; - /** Relevant window and action bar features flags. */ - private int mFeatures = DEFAULT_FEATURES; - /** Relevant user interface option flags. */ - private int mUiOptions = 0; - - /** Decor indeterminate progress indicator. */ - private IcsProgressBar mCircularProgressBar; - /** Decor progress indicator. */ - private IcsProgressBar mHorizontalProgressBar; - - /** Current displayed context action bar, if any. */ - private ActionMode mActionMode; - /** Parent view in which the context action bar is displayed. */ - private ActionBarContextView mActionModeView; - - /** Title view used with dialogs. */ - private TextView mTitleView; - /** Current activity title. */ - private CharSequence mTitle = null; - /** Whether or not this "activity" is floating (i.e., a dialog) */ - private boolean mIsFloating; - - - - /////////////////////////////////////////////////////////////////////////// - // Instance methods - /////////////////////////////////////////////////////////////////////////// - - @Override - public ActionBar getActionBar() { - if (DEBUG) Log.d(TAG, "[getActionBar]"); - - initActionBar(); - return aActionBar; - } - - private void initActionBar() { - if (DEBUG) Log.d(TAG, "[initActionBar]"); - - // Initializing the window decor can change window feature flags. - // Make sure that we have the correct set before performing the test below. - if (mDecor == null) { - installDecor(); - } - - if ((aActionBar != null) || !hasFeature(Window.FEATURE_ACTION_BAR) || hasFeature(Window.FEATURE_NO_TITLE) || mActivity.isChild()) { - return; - } - - aActionBar = new ActionBarImpl(mActivity, mFeatures); - - if (!mIsDelegate) { - //We may never get another chance to set the title - wActionBar.setWindowTitle(mActivity.getTitle()); - } - } - - @Override - protected Context getThemedContext() { - return aActionBar.getThemedContext(); - } - - @Override - public void setTitle(CharSequence title) { - if (DEBUG) Log.d(TAG, "[setTitle] title: " + title); - - dispatchTitleChanged(title, 0); - } - - @Override - public ActionMode startActionMode(ActionMode.Callback callback) { - if (DEBUG) Log.d(TAG, "[startActionMode] callback: " + callback); - - if (mActionMode != null) { - mActionMode.finish(); - } - - final ActionMode.Callback wrappedCallback = new ActionModeCallbackWrapper(callback); - ActionMode mode = null; - - //Emulate Activity's onWindowStartingActionMode: - initActionBar(); - if (aActionBar != null) { - mode = aActionBar.startActionMode(wrappedCallback); - } - - if (mode != null) { - mActionMode = mode; - } else { - if (mActionModeView == null) { - ViewStub stub = (ViewStub)mDecor.findViewById(R.id.abs__action_mode_bar_stub); - if (stub != null) { - mActionModeView = (ActionBarContextView)stub.inflate(); - } - } - if (mActionModeView != null) { - mActionModeView.killMode(); - mode = new StandaloneActionMode(mActivity, mActionModeView, wrappedCallback, true); - if (callback.onCreateActionMode(mode, mode.getMenu())) { - mode.invalidate(); - mActionModeView.initForMode(mode); - mActionModeView.setVisibility(View.VISIBLE); - mActionMode = mode; - mActionModeView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); - } else { - mActionMode = null; - } - } - } - if (mActionMode != null && mActivity instanceof OnActionModeStartedListener) { - ((OnActionModeStartedListener)mActivity).onActionModeStarted(mActionMode); - } - return mActionMode; - } - - - /////////////////////////////////////////////////////////////////////////// - // Lifecycle and interaction callbacks for delegation - /////////////////////////////////////////////////////////////////////////// - - @Override - public void dispatchConfigurationChanged(Configuration newConfig) { - if (DEBUG) Log.d(TAG, "[dispatchConfigurationChanged] newConfig: " + newConfig); - - if (aActionBar != null) { - aActionBar.onConfigurationChanged(newConfig); - } - } - - @Override - public void dispatchPostResume() { - if (DEBUG) Log.d(TAG, "[dispatchPostResume]"); - - if (aActionBar != null) { - aActionBar.setShowHideAnimationEnabled(true); - } - } - - @Override - public void dispatchPause() { - if (DEBUG) Log.d(TAG, "[dispatchPause]"); - - if (wActionBar != null && wActionBar.isOverflowMenuShowing()) { - wActionBar.hideOverflowMenu(); - } - } - - @Override - public void dispatchStop() { - if (DEBUG) Log.d(TAG, "[dispatchStop]"); - - if (aActionBar != null) { - aActionBar.setShowHideAnimationEnabled(false); - } - } - - @Override - public void dispatchInvalidateOptionsMenu() { - if (DEBUG) Log.d(TAG, "[dispatchInvalidateOptionsMenu]"); - - Bundle savedActionViewStates = null; - if (mMenu != null) { - savedActionViewStates = new Bundle(); - mMenu.saveActionViewStates(savedActionViewStates); - if (savedActionViewStates.size() > 0) { - mMenuFrozenActionViewState = savedActionViewStates; - } - // This will be started again when the panel is prepared. - mMenu.stopDispatchingItemsChanged(); - mMenu.clear(); - } - mMenuRefreshContent = true; - - // Prepare the options panel if we have an action bar - if (wActionBar != null) { - mMenuIsPrepared = false; - preparePanel(); - } - } - - @Override - public boolean dispatchOpenOptionsMenu() { - if (DEBUG) Log.d(TAG, "[dispatchOpenOptionsMenu]"); - - if (!isReservingOverflow()) { - return false; - } - - return wActionBar.showOverflowMenu(); - } - - @Override - public boolean dispatchCloseOptionsMenu() { - if (DEBUG) Log.d(TAG, "[dispatchCloseOptionsMenu]"); - - if (!isReservingOverflow()) { - return false; - } - - return wActionBar.hideOverflowMenu(); - } - - @Override - public void dispatchPostCreate(Bundle savedInstanceState) { - if (DEBUG) Log.d(TAG, "[dispatchOnPostCreate]"); - - if (mIsDelegate) { - mIsTitleReady = true; - } - - if (mDecor == null) { - initActionBar(); - } - } - - @Override - public boolean dispatchCreateOptionsMenu(android.view.Menu menu) { - if (DEBUG) { - Log.d(TAG, "[dispatchCreateOptionsMenu] android.view.Menu: " + menu); - Log.d(TAG, "[dispatchCreateOptionsMenu] returning true"); - } - return true; - } - - @Override - public boolean dispatchPrepareOptionsMenu(android.view.Menu menu) { - if (DEBUG) Log.d(TAG, "[dispatchPrepareOptionsMenu] android.view.Menu: " + menu); - - if (mActionMode != null) { - return false; - } - - mMenuIsPrepared = false; - if (!preparePanel()) { - return false; - } - - if (isReservingOverflow()) { - return false; - } - - if (mNativeItemMap == null) { - mNativeItemMap = new HashMap(); - } else { - mNativeItemMap.clear(); - } - - if (mMenu == null) { - return false; - } - - boolean result = mMenu.bindNativeOverflow(menu, this, mNativeItemMap); - if (DEBUG) Log.d(TAG, "[dispatchPrepareOptionsMenu] returning " + result); - return result; - } - - @Override - public boolean dispatchOptionsItemSelected(android.view.MenuItem item) { - throw new IllegalStateException("Native callback invoked. Create a test case and report!"); - } - - @Override - public boolean dispatchMenuOpened(int featureId, android.view.Menu menu) { - if (DEBUG) Log.d(TAG, "[dispatchMenuOpened] featureId: " + featureId + ", menu: " + menu); - - if (featureId == Window.FEATURE_ACTION_BAR || featureId == Window.FEATURE_OPTIONS_PANEL) { - if (aActionBar != null) { - aActionBar.dispatchMenuVisibilityChanged(true); - } - return true; - } - - return false; - } - - @Override - public void dispatchPanelClosed(int featureId, android.view.Menu menu){ - if (DEBUG) Log.d(TAG, "[dispatchPanelClosed] featureId: " + featureId + ", menu: " + menu); - - if (featureId == Window.FEATURE_ACTION_BAR || featureId == Window.FEATURE_OPTIONS_PANEL) { - if (aActionBar != null) { - aActionBar.dispatchMenuVisibilityChanged(false); - } - } - } - - @Override - public void dispatchTitleChanged(CharSequence title, int color) { - if (DEBUG) Log.d(TAG, "[dispatchTitleChanged] title: " + title + ", color: " + color); - - if (!mIsDelegate || mIsTitleReady) { - if (mTitleView != null) { - mTitleView.setText(title); - } else if (wActionBar != null) { - wActionBar.setWindowTitle(title); - } - } - - mTitle = title; - } - - @Override - public boolean dispatchKeyEvent(KeyEvent event) { - if (DEBUG) Log.d(TAG, "[dispatchKeyEvent] event: " + event); - - final int keyCode = event.getKeyCode(); - - // Not handled by the view hierarchy, does the action bar want it - // to cancel out of something special? - if (keyCode == KeyEvent.KEYCODE_BACK) { - final int action = event.getAction(); - // Back cancels action modes first. - if (mActionMode != null) { - if (action == KeyEvent.ACTION_UP) { - mActionMode.finish(); - } - if (DEBUG) Log.d(TAG, "[dispatchKeyEvent] returning true"); - return true; - } - - // Next collapse any expanded action views. - if (wActionBar != null && wActionBar.hasExpandedActionView()) { - if (action == KeyEvent.ACTION_UP) { - wActionBar.collapseActionView(); - } - if (DEBUG) Log.d(TAG, "[dispatchKeyEvent] returning true"); - return true; - } - } - - boolean result = false; - if (keyCode == KeyEvent.KEYCODE_MENU && isReservingOverflow()) { - if (event.getAction() == KeyEvent.ACTION_DOWN && event.isLongPress()) { - mMenuKeyIsLongPress = true; - } else if (event.getAction() == KeyEvent.ACTION_UP) { - if (!mMenuKeyIsLongPress) { - if (mActionMode == null && wActionBar != null) { - if (wActionBar.isOverflowMenuShowing()) { - wActionBar.hideOverflowMenu(); - } else { - wActionBar.showOverflowMenu(); - } - } - result = true; - } - mMenuKeyIsLongPress = false; - } - } - - if (DEBUG) Log.d(TAG, "[dispatchKeyEvent] returning " + result); - return result; - } - - @Override - public void dispatchDestroy() { - mIsDestroyed = true; - } - - - /////////////////////////////////////////////////////////////////////////// - // Menu callback lifecycle and creation - /////////////////////////////////////////////////////////////////////////// - - private boolean preparePanel() { - // Already prepared (isPrepared will be reset to false later) - if (mMenuIsPrepared) { - return true; - } - - // Init the panel state's menu--return false if init failed - if (mMenu == null || mMenuRefreshContent) { - if (mMenu == null) { - if (!initializePanelMenu() || (mMenu == null)) { - return false; - } - } - - if (wActionBar != null) { - wActionBar.setMenu(mMenu, this); - } - - // Call callback, and return if it doesn't want to display menu. - - // Creating the panel menu will involve a lot of manipulation; - // don't dispatch change events to presenters until we're done. - mMenu.stopDispatchingItemsChanged(); - if (!callbackCreateOptionsMenu(mMenu)) { - // Ditch the menu created above - mMenu = null; - - if (wActionBar != null) { - // Don't show it in the action bar either - wActionBar.setMenu(null, this); - } - - return false; - } - - mMenuRefreshContent = false; - } - - // Callback and return if the callback does not want to show the menu - - // Preparing the panel menu can involve a lot of manipulation; - // don't dispatch change events to presenters until we're done. - mMenu.stopDispatchingItemsChanged(); - - // Restore action view state before we prepare. This gives apps - // an opportunity to override frozen/restored state in onPrepare. - if (mMenuFrozenActionViewState != null) { - mMenu.restoreActionViewStates(mMenuFrozenActionViewState); - mMenuFrozenActionViewState = null; - } - - if (!callbackPrepareOptionsMenu(mMenu)) { - if (wActionBar != null) { - // The app didn't want to show the menu for now but it still exists. - // Clear it out of the action bar. - wActionBar.setMenu(null, this); - } - mMenu.startDispatchingItemsChanged(); - return false; - } - - // Set the proper keymap - KeyCharacterMap kmap = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD); - mMenu.setQwertyMode(kmap.getKeyboardType() != KeyCharacterMap.NUMERIC); - mMenu.startDispatchingItemsChanged(); - - // Set other state - mMenuIsPrepared = true; - - return true; - } - - public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) { - return callbackOptionsItemSelected(item); - } - - public void onMenuModeChange(MenuBuilder menu) { - reopenMenu(true); - } - - private void reopenMenu(boolean toggleMenuMode) { - if (wActionBar != null && wActionBar.isOverflowReserved()) { - if (!wActionBar.isOverflowMenuShowing() || !toggleMenuMode) { - if (wActionBar.getVisibility() == View.VISIBLE) { - if (callbackPrepareOptionsMenu(mMenu)) { - wActionBar.showOverflowMenu(); - } - } - } else { - wActionBar.hideOverflowMenu(); - } - return; - } - } - - private boolean initializePanelMenu() { - Context context = mActivity;//getContext(); - - // If we have an action bar, initialize the menu with a context themed for it. - if (wActionBar != null) { - TypedValue outValue = new TypedValue(); - Resources.Theme currentTheme = context.getTheme(); - currentTheme.resolveAttribute(R.attr.actionBarWidgetTheme, - outValue, true); - final int targetThemeRes = outValue.resourceId; - - if (targetThemeRes != 0 /*&& context.getThemeResId() != targetThemeRes*/) { - context = new ContextThemeWrapper(context, targetThemeRes); - } - } - - mMenu = new MenuBuilder(context); - mMenu.setCallback(this); - - return true; - } - - void checkCloseActionMenu(Menu menu) { - if (mClosingActionMenu) { - return; - } - - mClosingActionMenu = true; - wActionBar.dismissPopupMenus(); - //Callback cb = getCallback(); - //if (cb != null && !isDestroyed()) { - // cb.onPanelClosed(FEATURE_ACTION_BAR, menu); - //} - mClosingActionMenu = false; - } - - @Override - public boolean onOpenSubMenu(MenuBuilder subMenu) { - return true; - } - - @Override - public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) { - checkCloseActionMenu(menu); - } - - @Override - public boolean onMenuItemClick(android.view.MenuItem item) { - if (DEBUG) Log.d(TAG, "[mNativeItemListener.onMenuItemClick] item: " + item); - - final MenuItemImpl sherlockItem = mNativeItemMap.get(item); - if (sherlockItem != null) { - sherlockItem.invoke(); - } else { - Log.e(TAG, "Options item \"" + item + "\" not found in mapping"); - } - - return true; //Do not allow continuation of native handling - } - - @Override - public boolean onMenuItemSelected(int featureId, MenuItem item) { - return callbackOptionsItemSelected(item); - } - - - /////////////////////////////////////////////////////////////////////////// - // Progress bar interaction and internal handling - /////////////////////////////////////////////////////////////////////////// - - @Override - public void setProgressBarVisibility(boolean visible) { - if (DEBUG) Log.d(TAG, "[setProgressBarVisibility] visible: " + visible); - - setFeatureInt(Window.FEATURE_PROGRESS, visible ? Window.PROGRESS_VISIBILITY_ON : - Window.PROGRESS_VISIBILITY_OFF); - } - - @Override - public void setProgressBarIndeterminateVisibility(boolean visible) { - if (DEBUG) Log.d(TAG, "[setProgressBarIndeterminateVisibility] visible: " + visible); - - setFeatureInt(Window.FEATURE_INDETERMINATE_PROGRESS, - visible ? Window.PROGRESS_VISIBILITY_ON : Window.PROGRESS_VISIBILITY_OFF); - } - - @Override - public void setProgressBarIndeterminate(boolean indeterminate) { - if (DEBUG) Log.d(TAG, "[setProgressBarIndeterminate] indeterminate: " + indeterminate); - - setFeatureInt(Window.FEATURE_PROGRESS, - indeterminate ? Window.PROGRESS_INDETERMINATE_ON : Window.PROGRESS_INDETERMINATE_OFF); - } - - @Override - public void setProgress(int progress) { - if (DEBUG) Log.d(TAG, "[setProgress] progress: " + progress); - - setFeatureInt(Window.FEATURE_PROGRESS, progress + Window.PROGRESS_START); - } - - @Override - public void setSecondaryProgress(int secondaryProgress) { - if (DEBUG) Log.d(TAG, "[setSecondaryProgress] secondaryProgress: " + secondaryProgress); - - setFeatureInt(Window.FEATURE_PROGRESS, - secondaryProgress + Window.PROGRESS_SECONDARY_START); - } - - private void setFeatureInt(int featureId, int value) { - updateInt(featureId, value, false); - } - - private void updateInt(int featureId, int value, boolean fromResume) { - // Do nothing if the decor is not yet installed... an update will - // need to be forced when we eventually become active. - if (mContentParent == null) { - return; - } - - final int featureMask = 1 << featureId; - - if ((getFeatures() & featureMask) == 0 && !fromResume) { - return; - } - - onIntChanged(featureId, value); - } - - private void onIntChanged(int featureId, int value) { - if (featureId == Window.FEATURE_PROGRESS || featureId == Window.FEATURE_INDETERMINATE_PROGRESS) { - updateProgressBars(value); - } - } - - private void updateProgressBars(int value) { - IcsProgressBar circularProgressBar = getCircularProgressBar(true); - IcsProgressBar horizontalProgressBar = getHorizontalProgressBar(true); - - final int features = mFeatures;//getLocalFeatures(); - if (value == Window.PROGRESS_VISIBILITY_ON) { - if ((features & (1 << Window.FEATURE_PROGRESS)) != 0) { - int level = horizontalProgressBar.getProgress(); - int visibility = (horizontalProgressBar.isIndeterminate() || level < 10000) ? - View.VISIBLE : View.INVISIBLE; - horizontalProgressBar.setVisibility(visibility); - } - if ((features & (1 << Window.FEATURE_INDETERMINATE_PROGRESS)) != 0) { - circularProgressBar.setVisibility(View.VISIBLE); - } - } else if (value == Window.PROGRESS_VISIBILITY_OFF) { - if ((features & (1 << Window.FEATURE_PROGRESS)) != 0) { - horizontalProgressBar.setVisibility(View.GONE); - } - if ((features & (1 << Window.FEATURE_INDETERMINATE_PROGRESS)) != 0) { - circularProgressBar.setVisibility(View.GONE); - } - } else if (value == Window.PROGRESS_INDETERMINATE_ON) { - horizontalProgressBar.setIndeterminate(true); - } else if (value == Window.PROGRESS_INDETERMINATE_OFF) { - horizontalProgressBar.setIndeterminate(false); - } else if (Window.PROGRESS_START <= value && value <= Window.PROGRESS_END) { - // We want to set the progress value before testing for visibility - // so that when the progress bar becomes visible again, it has the - // correct level. - horizontalProgressBar.setProgress(value - Window.PROGRESS_START); - - if (value < Window.PROGRESS_END) { - showProgressBars(horizontalProgressBar, circularProgressBar); - } else { - hideProgressBars(horizontalProgressBar, circularProgressBar); - } - } else if (Window.PROGRESS_SECONDARY_START <= value && value <= Window.PROGRESS_SECONDARY_END) { - horizontalProgressBar.setSecondaryProgress(value - Window.PROGRESS_SECONDARY_START); - - showProgressBars(horizontalProgressBar, circularProgressBar); - } - } - - private void showProgressBars(IcsProgressBar horizontalProgressBar, IcsProgressBar spinnyProgressBar) { - final int features = mFeatures;//getLocalFeatures(); - if ((features & (1 << Window.FEATURE_INDETERMINATE_PROGRESS)) != 0 && - spinnyProgressBar.getVisibility() == View.INVISIBLE) { - spinnyProgressBar.setVisibility(View.VISIBLE); - } - // Only show the progress bars if the primary progress is not complete - if ((features & (1 << Window.FEATURE_PROGRESS)) != 0 && - horizontalProgressBar.getProgress() < 10000) { - horizontalProgressBar.setVisibility(View.VISIBLE); - } - } - - private void hideProgressBars(IcsProgressBar horizontalProgressBar, IcsProgressBar spinnyProgressBar) { - final int features = mFeatures;//getLocalFeatures(); - Animation anim = AnimationUtils.loadAnimation(mActivity, android.R.anim.fade_out); - anim.setDuration(1000); - if ((features & (1 << Window.FEATURE_INDETERMINATE_PROGRESS)) != 0 && - spinnyProgressBar.getVisibility() == View.VISIBLE) { - spinnyProgressBar.startAnimation(anim); - spinnyProgressBar.setVisibility(View.INVISIBLE); - } - if ((features & (1 << Window.FEATURE_PROGRESS)) != 0 && - horizontalProgressBar.getVisibility() == View.VISIBLE) { - horizontalProgressBar.startAnimation(anim); - horizontalProgressBar.setVisibility(View.INVISIBLE); - } - } - - private IcsProgressBar getCircularProgressBar(boolean shouldInstallDecor) { - if (mCircularProgressBar != null) { - return mCircularProgressBar; - } - if (mContentParent == null && shouldInstallDecor) { - installDecor(); - } - mCircularProgressBar = (IcsProgressBar)mDecor.findViewById(R.id.abs__progress_circular); - if (mCircularProgressBar != null) { - mCircularProgressBar.setVisibility(View.INVISIBLE); - } - return mCircularProgressBar; - } - - private IcsProgressBar getHorizontalProgressBar(boolean shouldInstallDecor) { - if (mHorizontalProgressBar != null) { - return mHorizontalProgressBar; - } - if (mContentParent == null && shouldInstallDecor) { - installDecor(); - } - mHorizontalProgressBar = (IcsProgressBar)mDecor.findViewById(R.id.abs__progress_horizontal); - if (mHorizontalProgressBar != null) { - mHorizontalProgressBar.setVisibility(View.INVISIBLE); - } - return mHorizontalProgressBar; - } - - - /////////////////////////////////////////////////////////////////////////// - // Feature management and content interaction and creation - /////////////////////////////////////////////////////////////////////////// - - private int getFeatures() { - if (DEBUG) Log.d(TAG, "[getFeatures] returning " + mFeatures); - - return mFeatures; - } - - @Override - public boolean hasFeature(int featureId) { - if (DEBUG) Log.d(TAG, "[hasFeature] featureId: " + featureId); - - boolean result = (mFeatures & (1 << featureId)) != 0; - if (DEBUG) Log.d(TAG, "[hasFeature] returning " + result); - return result; - } - - @Override - public boolean requestFeature(int featureId) { - if (DEBUG) Log.d(TAG, "[requestFeature] featureId: " + featureId); - - if (mContentParent != null) { - throw new AndroidRuntimeException("requestFeature() must be called before adding content"); - } - - switch (featureId) { - case Window.FEATURE_ACTION_BAR: - case Window.FEATURE_ACTION_BAR_OVERLAY: - case Window.FEATURE_ACTION_MODE_OVERLAY: - case Window.FEATURE_INDETERMINATE_PROGRESS: - case Window.FEATURE_NO_TITLE: - case Window.FEATURE_PROGRESS: - mFeatures |= (1 << featureId); - return true; - - default: - return false; - } - } - - @Override - public void setUiOptions(int uiOptions) { - if (DEBUG) Log.d(TAG, "[setUiOptions] uiOptions: " + uiOptions); - - mUiOptions = uiOptions; - } - - @Override - public void setUiOptions(int uiOptions, int mask) { - if (DEBUG) Log.d(TAG, "[setUiOptions] uiOptions: " + uiOptions + ", mask: " + mask); - - mUiOptions = (mUiOptions & ~mask) | (uiOptions & mask); - } - - @Override - public void setContentView(int layoutResId) { - if (DEBUG) Log.d(TAG, "[setContentView] layoutResId: " + layoutResId); - - if (mContentParent == null) { - installDecor(); - } else { - mContentParent.removeAllViews(); - } - mActivity.getLayoutInflater().inflate(layoutResId, mContentParent); - - android.view.Window.Callback callback = mActivity.getWindow().getCallback(); - if (callback != null) { - callback.onContentChanged(); - } - - initActionBar(); - } - - @Override - public void setContentView(View view, ViewGroup.LayoutParams params) { - if (DEBUG) Log.d(TAG, "[setContentView] view: " + view + ", params: " + params); - - if (mContentParent == null) { - installDecor(); - } else { - mContentParent.removeAllViews(); - } - mContentParent.addView(view, params); - - android.view.Window.Callback callback = mActivity.getWindow().getCallback(); - if (callback != null) { - callback.onContentChanged(); - } - - initActionBar(); - } - - @Override - public void addContentView(View view, ViewGroup.LayoutParams params) { - if (DEBUG) Log.d(TAG, "[addContentView] view: " + view + ", params: " + params); - - if (mContentParent == null) { - installDecor(); - } - mContentParent.addView(view, params); - - initActionBar(); - } - - private void installDecor() { - if (DEBUG) Log.d(TAG, "[installDecor]"); - - if (mDecor == null) { - mDecor = (ViewGroup)mActivity.getWindow().getDecorView().findViewById(android.R.id.content); - } - if (mContentParent == null) { - //Since we are not operating at the window level we need to take - //into account the fact that the true decor may have already been - //initialized and had content attached to it. If that is the case, - //copy over its children to our new content container. - List views = null; - if (mDecor.getChildCount() > 0) { - views = new ArrayList(1); //Usually there's only one child - for (int i = 0, children = mDecor.getChildCount(); i < children; i++) { - View child = mDecor.getChildAt(0); - mDecor.removeView(child); - views.add(child); - } - } - - mContentParent = generateLayout(); - - //Copy over the old children. See above for explanation. - if (views != null) { - for (View child : views) { - mContentParent.addView(child); - } - } - - mTitleView = (TextView)mDecor.findViewById(android.R.id.title); - if (mTitleView != null) { - if (hasFeature(Window.FEATURE_NO_TITLE)) { - mTitleView.setVisibility(View.GONE); - if (mContentParent instanceof FrameLayout) { - ((FrameLayout)mContentParent).setForeground(null); - } - } else { - mTitleView.setText(mTitle); - } - } else { - wActionBar = (ActionBarView)mDecor.findViewById(R.id.abs__action_bar); - if (wActionBar != null) { - wActionBar.setWindowCallback(this); - if (wActionBar.getTitle() == null) { - wActionBar.setWindowTitle(mActivity.getTitle()); - } - if (hasFeature(Window.FEATURE_PROGRESS)) { - wActionBar.initProgress(); - } - if (hasFeature(Window.FEATURE_INDETERMINATE_PROGRESS)) { - wActionBar.initIndeterminateProgress(); - } - - //Since we don't require onCreate dispatching, parse for uiOptions here - int uiOptions = loadUiOptionsFromManifest(mActivity); - if (uiOptions != 0) { - mUiOptions = uiOptions; - } - - boolean splitActionBar = false; - final boolean splitWhenNarrow = (mUiOptions & ActivityInfo.UIOPTION_SPLIT_ACTION_BAR_WHEN_NARROW) != 0; - if (splitWhenNarrow) { - splitActionBar = getResources_getBoolean(mActivity, R.bool.abs__split_action_bar_is_narrow); - } else { - splitActionBar = mActivity.getTheme() - .obtainStyledAttributes(R.styleable.SherlockTheme) - .getBoolean(R.styleable.SherlockTheme_windowSplitActionBar, false); - } - final ActionBarContainer splitView = (ActionBarContainer)mDecor.findViewById(R.id.abs__split_action_bar); - if (splitView != null) { - wActionBar.setSplitView(splitView); - wActionBar.setSplitActionBar(splitActionBar); - wActionBar.setSplitWhenNarrow(splitWhenNarrow); - - mActionModeView = (ActionBarContextView)mDecor.findViewById(R.id.abs__action_context_bar); - mActionModeView.setSplitView(splitView); - mActionModeView.setSplitActionBar(splitActionBar); - mActionModeView.setSplitWhenNarrow(splitWhenNarrow); - } else if (splitActionBar) { - Log.e(TAG, "Requested split action bar with incompatible window decor! Ignoring request."); - } - - // Post the panel invalidate for later; avoid application onCreateOptionsMenu - // being called in the middle of onCreate or similar. - mDecor.post(new Runnable() { - @Override - public void run() { - //Invalidate if the panel menu hasn't been created before this. - if (!mIsDestroyed && !mActivity.isFinishing() && mMenu == null) { - dispatchInvalidateOptionsMenu(); - } - } - }); - } - } - } - } - - private ViewGroup generateLayout() { - if (DEBUG) Log.d(TAG, "[generateLayout]"); - - // Apply data from current theme. - - TypedArray a = mActivity.getTheme().obtainStyledAttributes(R.styleable.SherlockTheme); - - mIsFloating = a.getBoolean(R.styleable.SherlockTheme_android_windowIsFloating, false); - - if (!a.hasValue(R.styleable.SherlockTheme_windowActionBar)) { - throw new IllegalStateException("You must use Theme.Sherlock, Theme.Sherlock.Light, Theme.Sherlock.Light.DarkActionBar, or a derivative."); - } - - if (a.getBoolean(R.styleable.SherlockTheme_windowNoTitle, false)) { - requestFeature(Window.FEATURE_NO_TITLE); - } else if (a.getBoolean(R.styleable.SherlockTheme_windowActionBar, false)) { - // Don't allow an action bar if there is no title. - requestFeature(Window.FEATURE_ACTION_BAR); - } - - if (a.getBoolean(R.styleable.SherlockTheme_windowActionBarOverlay, false)) { - requestFeature(Window.FEATURE_ACTION_BAR_OVERLAY); - } - - if (a.getBoolean(R.styleable.SherlockTheme_windowActionModeOverlay, false)) { - requestFeature(Window.FEATURE_ACTION_MODE_OVERLAY); - } - - a.recycle(); - - int layoutResource; - if (!hasFeature(Window.FEATURE_NO_TITLE)) { - if (mIsFloating) { - //Trash original dialog LinearLayout - mDecor = (ViewGroup)mDecor.getParent(); - mDecor.removeAllViews(); - - layoutResource = R.layout.abs__dialog_title_holo; - } else { - if (hasFeature(Window.FEATURE_ACTION_BAR_OVERLAY)) { - layoutResource = R.layout.abs__screen_action_bar_overlay; - } else { - layoutResource = R.layout.abs__screen_action_bar; - } - } - } else if (hasFeature(Window.FEATURE_ACTION_MODE_OVERLAY) && !hasFeature(Window.FEATURE_NO_TITLE)) { - layoutResource = R.layout.abs__screen_simple_overlay_action_mode; - } else { - layoutResource = R.layout.abs__screen_simple; - } - - if (DEBUG) Log.d(TAG, "[generateLayout] using screen XML " + mActivity.getResources().getString(layoutResource)); - View in = mActivity.getLayoutInflater().inflate(layoutResource, null); - mDecor.addView(in, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT)); - - ViewGroup contentParent = (ViewGroup)mDecor.findViewById(R.id.abs__content); - if (contentParent == null) { - throw new RuntimeException("Couldn't find content container view"); - } - - //Make our new child the true content view (for fragments). VERY VOLATILE! - mDecor.setId(View.NO_ID); - contentParent.setId(android.R.id.content); - - if (hasFeature(Window.FEATURE_INDETERMINATE_PROGRESS)) { - IcsProgressBar progress = getCircularProgressBar(false); - if (progress != null) { - progress.setIndeterminate(true); - } - } - - return contentParent; - } - - - /////////////////////////////////////////////////////////////////////////// - // Miscellaneous - /////////////////////////////////////////////////////////////////////////// - - /** - * Determine whether or not the device has a dedicated menu key. - * - * @return {@code true} if native menu key is present. - */ - private boolean isReservingOverflow() { - if (!mReserveOverflowSet) { - mReserveOverflow = ActionMenuPresenter.reserveOverflow(mActivity); - mReserveOverflowSet = true; - } - return mReserveOverflow; - } - - private static int loadUiOptionsFromManifest(Activity activity) { - int uiOptions = 0; - try { - final String thisPackage = activity.getClass().getName(); - if (DEBUG) Log.i(TAG, "Parsing AndroidManifest.xml for " + thisPackage); - - final String packageName = activity.getApplicationInfo().packageName; - final AssetManager am = activity.createPackageContext(packageName, 0).getAssets(); - final XmlResourceParser xml = am.openXmlResourceParser("AndroidManifest.xml"); - - int eventType = xml.getEventType(); - while (eventType != XmlPullParser.END_DOCUMENT) { - if (eventType == XmlPullParser.START_TAG) { - String name = xml.getName(); - - if ("application".equals(name)) { - //Check if the has the attribute - if (DEBUG) Log.d(TAG, "Got "); - - for (int i = xml.getAttributeCount() - 1; i >= 0; i--) { - if (DEBUG) Log.d(TAG, xml.getAttributeName(i) + ": " + xml.getAttributeValue(i)); - - if ("uiOptions".equals(xml.getAttributeName(i))) { - uiOptions = xml.getAttributeIntValue(i, 0); - break; //out of for loop - } - } - } else if ("activity".equals(name)) { - //Check if the is us and has the attribute - if (DEBUG) Log.d(TAG, "Got "); - Integer activityUiOptions = null; - String activityPackage = null; - boolean isOurActivity = false; - - for (int i = xml.getAttributeCount() - 1; i >= 0; i--) { - if (DEBUG) Log.d(TAG, xml.getAttributeName(i) + ": " + xml.getAttributeValue(i)); - - //We need both uiOptions and name attributes - String attrName = xml.getAttributeName(i); - if ("uiOptions".equals(attrName)) { - activityUiOptions = xml.getAttributeIntValue(i, 0); - } else if ("name".equals(attrName)) { - activityPackage = cleanActivityName(packageName, xml.getAttributeValue(i)); - if (!thisPackage.equals(activityPackage)) { - break; //out of for loop - } - isOurActivity = true; - } - - //Make sure we have both attributes before processing - if ((activityUiOptions != null) && (activityPackage != null)) { - //Our activity, uiOptions specified, override with our value - uiOptions = activityUiOptions.intValue(); - } - } - if (isOurActivity) { - //If we matched our activity but it had no logo don't - //do any more processing of the manifest - break; - } - } - } - eventType = xml.nextToken(); - } - } catch (Exception e) { - e.printStackTrace(); - } - if (DEBUG) Log.i(TAG, "Returning " + Integer.toHexString(uiOptions)); - return uiOptions; - } - - public static String cleanActivityName(String manifestPackage, String activityName) { - if (activityName.charAt(0) == '.') { - //Relative activity name (e.g., android:name=".ui.SomeClass") - return manifestPackage + activityName; - } - if (activityName.indexOf('.', 1) == -1) { - //Unqualified activity name (e.g., android:name="SomeClass") - return manifestPackage + "." + activityName; - } - //Fully-qualified activity name (e.g., "com.my.package.SomeClass") - return activityName; - } - - /** - * Clears out internal reference when the action mode is destroyed. - */ - private class ActionModeCallbackWrapper implements ActionMode.Callback { - private final ActionMode.Callback mWrapped; - - public ActionModeCallbackWrapper(ActionMode.Callback wrapped) { - mWrapped = wrapped; - } - - public boolean onCreateActionMode(ActionMode mode, Menu menu) { - return mWrapped.onCreateActionMode(mode, menu); - } - - public boolean onPrepareActionMode(ActionMode mode, Menu menu) { - return mWrapped.onPrepareActionMode(mode, menu); - } - - public boolean onActionItemClicked(ActionMode mode, MenuItem item) { - return mWrapped.onActionItemClicked(mode, item); - } - - public void onDestroyActionMode(ActionMode mode) { - mWrapped.onDestroyActionMode(mode); - if (mActionModeView != null) { - mActionModeView.setVisibility(View.GONE); - mActionModeView.removeAllViews(); - } - if (mActivity instanceof OnActionModeFinishedListener) { - ((OnActionModeFinishedListener)mActivity).onActionModeFinished(mActionMode); - } - mActionMode = null; - } - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/ActionBarSherlockNative.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/ActionBarSherlockNative.java deleted file mode 100644 index 9afca185a..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/ActionBarSherlockNative.java +++ /dev/null @@ -1,328 +0,0 @@ -package com.actionbarsherlock.internal; - -import com.actionbarsherlock.ActionBarSherlock; -import com.actionbarsherlock.app.ActionBar; -import com.actionbarsherlock.internal.app.ActionBarWrapper; -import com.actionbarsherlock.internal.view.menu.MenuWrapper; -import com.actionbarsherlock.view.ActionMode; -import com.actionbarsherlock.view.MenuInflater; -import android.app.Activity; -import android.content.Context; -import android.util.Log; -import android.util.TypedValue; -import android.view.ContextThemeWrapper; -import android.view.View; -import android.view.Window; -import android.view.ViewGroup.LayoutParams; - -@ActionBarSherlock.Implementation(api = 14) -public class ActionBarSherlockNative extends ActionBarSherlock { - private ActionBarWrapper mActionBar; - private ActionModeWrapper mActionMode; - private MenuWrapper mMenu; - - public ActionBarSherlockNative(Activity activity, int flags) { - super(activity, flags); - } - - - @Override - public ActionBar getActionBar() { - if (DEBUG) Log.d(TAG, "[getActionBar]"); - - initActionBar(); - return mActionBar; - } - - private void initActionBar() { - if (mActionBar != null || mActivity.getActionBar() == null) { - return; - } - - mActionBar = new ActionBarWrapper(mActivity); - } - - @Override - public void dispatchInvalidateOptionsMenu() { - if (DEBUG) Log.d(TAG, "[dispatchInvalidateOptionsMenu]"); - - mActivity.getWindow().invalidatePanelMenu(Window.FEATURE_OPTIONS_PANEL); - } - - @Override - public boolean dispatchCreateOptionsMenu(android.view.Menu menu) { - if (DEBUG) Log.d(TAG, "[dispatchCreateOptionsMenu] menu: " + menu); - - if (mMenu == null || menu != mMenu.unwrap()) { - mMenu = new MenuWrapper(menu); - } - - final boolean result = callbackCreateOptionsMenu(mMenu); - if (DEBUG) Log.d(TAG, "[dispatchCreateOptionsMenu] returning " + result); - return result; - } - - @Override - public boolean dispatchPrepareOptionsMenu(android.view.Menu menu) { - if (DEBUG) Log.d(TAG, "[dispatchPrepareOptionsMenu] menu: " + menu); - - final boolean result = callbackPrepareOptionsMenu(mMenu); - if (DEBUG) Log.d(TAG, "[dispatchPrepareOptionsMenu] returning " + result); - return result; - } - - @Override - public boolean dispatchOptionsItemSelected(android.view.MenuItem item) { - if (DEBUG) Log.d(TAG, "[dispatchOptionsItemSelected] item: " + item.getTitleCondensed()); - - final boolean result = callbackOptionsItemSelected(mMenu.findItem(item)); - if (DEBUG) Log.d(TAG, "[dispatchOptionsItemSelected] returning " + result); - return result; - } - - @Override - public boolean hasFeature(int feature) { - if (DEBUG) Log.d(TAG, "[hasFeature] feature: " + feature); - - final boolean result = mActivity.getWindow().hasFeature(feature); - if (DEBUG) Log.d(TAG, "[hasFeature] returning " + result); - return result; - } - - @Override - public boolean requestFeature(int featureId) { - if (DEBUG) Log.d(TAG, "[requestFeature] featureId: " + featureId); - - final boolean result = mActivity.getWindow().requestFeature(featureId); - if (DEBUG) Log.d(TAG, "[requestFeature] returning " + result); - return result; - } - - @Override - public void setUiOptions(int uiOptions) { - if (DEBUG) Log.d(TAG, "[setUiOptions] uiOptions: " + uiOptions); - - mActivity.getWindow().setUiOptions(uiOptions); - } - - @Override - public void setUiOptions(int uiOptions, int mask) { - if (DEBUG) Log.d(TAG, "[setUiOptions] uiOptions: " + uiOptions + ", mask: " + mask); - - mActivity.getWindow().setUiOptions(uiOptions, mask); - } - - @Override - public void setContentView(int layoutResId) { - if (DEBUG) Log.d(TAG, "[setContentView] layoutResId: " + layoutResId); - - mActivity.getWindow().setContentView(layoutResId); - initActionBar(); - } - - @Override - public void setContentView(View view, LayoutParams params) { - if (DEBUG) Log.d(TAG, "[setContentView] view: " + view + ", params: " + params); - - mActivity.getWindow().setContentView(view, params); - initActionBar(); - } - - @Override - public void addContentView(View view, LayoutParams params) { - if (DEBUG) Log.d(TAG, "[addContentView] view: " + view + ", params: " + params); - - mActivity.getWindow().addContentView(view, params); - initActionBar(); - } - - @Override - public void setTitle(CharSequence title) { - if (DEBUG) Log.d(TAG, "[setTitle] title: " + title); - - mActivity.getWindow().setTitle(title); - } - - @Override - public void setProgressBarVisibility(boolean visible) { - if (DEBUG) Log.d(TAG, "[setProgressBarVisibility] visible: " + visible); - - mActivity.setProgressBarVisibility(visible); - } - - @Override - public void setProgressBarIndeterminateVisibility(boolean visible) { - if (DEBUG) Log.d(TAG, "[setProgressBarIndeterminateVisibility] visible: " + visible); - - mActivity.setProgressBarIndeterminateVisibility(visible); - } - - @Override - public void setProgressBarIndeterminate(boolean indeterminate) { - if (DEBUG) Log.d(TAG, "[setProgressBarIndeterminate] indeterminate: " + indeterminate); - - mActivity.setProgressBarIndeterminate(indeterminate); - } - - @Override - public void setProgress(int progress) { - if (DEBUG) Log.d(TAG, "[setProgress] progress: " + progress); - - mActivity.setProgress(progress); - } - - @Override - public void setSecondaryProgress(int secondaryProgress) { - if (DEBUG) Log.d(TAG, "[setSecondaryProgress] secondaryProgress: " + secondaryProgress); - - mActivity.setSecondaryProgress(secondaryProgress); - } - - @Override - protected Context getThemedContext() { - Context context = mActivity; - TypedValue outValue = new TypedValue(); - mActivity.getTheme().resolveAttribute(android.R.attr.actionBarWidgetTheme, outValue, true); - if (outValue.resourceId != 0) { - //We are unable to test if this is the same as our current theme - //so we just wrap it and hope that if the attribute was specified - //then the user is intentionally specifying an alternate theme. - context = new ContextThemeWrapper(context, outValue.resourceId); - } - return context; - } - - @Override - public ActionMode startActionMode(com.actionbarsherlock.view.ActionMode.Callback callback) { - if (DEBUG) Log.d(TAG, "[startActionMode] callback: " + callback); - - if (mActionMode != null) { - mActionMode.finish(); - } - ActionModeCallbackWrapper wrapped = null; - if (callback != null) { - wrapped = new ActionModeCallbackWrapper(callback); - } - - //Calling this will trigger the callback wrapper's onCreate which - //is where we will set the new instance to mActionMode since we need - //to pass it through to the sherlock callbacks and the call below - //will not have returned yet to store its value. - mActivity.startActionMode(wrapped); - - return mActionMode; - } - - private class ActionModeCallbackWrapper implements android.view.ActionMode.Callback { - private final ActionMode.Callback mCallback; - - public ActionModeCallbackWrapper(ActionMode.Callback callback) { - mCallback = callback; - } - - @Override - public boolean onCreateActionMode(android.view.ActionMode mode, android.view.Menu menu) { - //See ActionBarSherlockNative#startActionMode - mActionMode = new ActionModeWrapper(mode); - - return mCallback.onCreateActionMode(mActionMode, mActionMode.getMenu()); - } - - @Override - public boolean onPrepareActionMode(android.view.ActionMode mode, android.view.Menu menu) { - return mCallback.onPrepareActionMode(mActionMode, mActionMode.getMenu()); - } - - @Override - public boolean onActionItemClicked(android.view.ActionMode mode, android.view.MenuItem item) { - return mCallback.onActionItemClicked(mActionMode, mActionMode.getMenu().findItem(item)); - } - - @Override - public void onDestroyActionMode(android.view.ActionMode mode) { - mCallback.onDestroyActionMode(mActionMode); - } - } - - private class ActionModeWrapper extends ActionMode { - private final android.view.ActionMode mActionMode; - private MenuWrapper mMenu = null; - - ActionModeWrapper(android.view.ActionMode actionMode) { - mActionMode = actionMode; - } - - @Override - public void setTitle(CharSequence title) { - mActionMode.setTitle(title); - } - - @Override - public void setTitle(int resId) { - mActionMode.setTitle(resId); - } - - @Override - public void setSubtitle(CharSequence subtitle) { - mActionMode.setSubtitle(subtitle); - } - - @Override - public void setSubtitle(int resId) { - mActionMode.setSubtitle(resId); - } - - @Override - public void setCustomView(View view) { - mActionMode.setCustomView(view); - } - - @Override - public void invalidate() { - mActionMode.invalidate(); - } - - @Override - public void finish() { - mActionMode.finish(); - } - - @Override - public MenuWrapper getMenu() { - if (mMenu == null) { - mMenu = new MenuWrapper(mActionMode.getMenu()); - } - return mMenu; - } - - @Override - public CharSequence getTitle() { - return mActionMode.getTitle(); - } - - @Override - public CharSequence getSubtitle() { - return mActionMode.getSubtitle(); - } - - @Override - public View getCustomView() { - return mActionMode.getCustomView(); - } - - @Override - public MenuInflater getMenuInflater() { - return ActionBarSherlockNative.this.getMenuInflater(); - } - - @Override - public void setTag(Object tag) { - mActionMode.setTag(tag); - } - - @Override - public Object getTag() { - return mActionMode.getTag(); - } - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/ResourcesCompat.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/ResourcesCompat.java deleted file mode 100644 index 8e1efe8c5..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/ResourcesCompat.java +++ /dev/null @@ -1,95 +0,0 @@ -package com.actionbarsherlock.internal; - -import android.content.Context; -import android.os.Build; -import android.util.DisplayMetrics; -import com.actionbarsherlock.R; - -public final class ResourcesCompat { - //No instances - private ResourcesCompat() {} - - - /** - * Support implementation of {@code getResources().getBoolean()} that we - * can use to simulate filtering based on width and smallest width - * qualifiers on pre-3.2. - * - * @param context Context to load booleans from on 3.2+ and to fetch the - * display metrics. - * @param id Id of boolean to load. - * @return Associated boolean value as reflected by the current display - * metrics. - */ - public static boolean getResources_getBoolean(Context context, int id) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) { - return context.getResources().getBoolean(id); - } - - DisplayMetrics metrics = context.getResources().getDisplayMetrics(); - float widthDp = metrics.widthPixels / metrics.density; - float heightDp = metrics.heightPixels / metrics.density; - float smallestWidthDp = (widthDp < heightDp) ? widthDp : heightDp; - - if (id == R.bool.abs__action_bar_embed_tabs) { - if (widthDp >= 480) { - return true; //values-w480dp - } - return false; //values - } - if (id == R.bool.abs__split_action_bar_is_narrow) { - if (widthDp >= 480) { - return false; //values-w480dp - } - return true; //values - } - if (id == R.bool.abs__action_bar_expanded_action_views_exclusive) { - if (smallestWidthDp >= 600) { - return false; //values-sw600dp - } - return true; //values - } - if (id == R.bool.abs__config_allowActionMenuItemTextWithIcon) { - if (widthDp >= 480) { - return true; //values-w480dp - } - return false; //values - } - - throw new IllegalArgumentException("Unknown boolean resource ID " + id); - } - - /** - * Support implementation of {@code getResources().getInteger()} that we - * can use to simulate filtering based on width qualifiers on pre-3.2. - * - * @param context Context to load integers from on 3.2+ and to fetch the - * display metrics. - * @param id Id of integer to load. - * @return Associated integer value as reflected by the current display - * metrics. - */ - public static int getResources_getInteger(Context context, int id) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) { - return context.getResources().getInteger(id); - } - - DisplayMetrics metrics = context.getResources().getDisplayMetrics(); - float widthDp = metrics.widthPixels / metrics.density; - - if (id == R.integer.abs__max_action_buttons) { - if (widthDp >= 600) { - return 5; //values-w600dp - } - if (widthDp >= 500) { - return 4; //values-w500dp - } - if (widthDp >= 360) { - return 3; //values-w360dp - } - return 2; //values - } - - throw new IllegalArgumentException("Unknown integer resource ID " + id); - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/app/ActionBarImpl.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/app/ActionBarImpl.java deleted file mode 100644 index 6ae0402c0..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/app/ActionBarImpl.java +++ /dev/null @@ -1,1026 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.app; - -import java.lang.ref.WeakReference; -import java.util.ArrayList; -import android.app.Activity; -import android.app.Dialog; -import android.content.Context; -import android.content.res.Configuration; -import android.content.res.Resources; -import android.graphics.drawable.Drawable; -import android.os.Build; -import android.os.Handler; -import android.support.v4.app.FragmentTransaction; -import android.util.TypedValue; -import android.view.ContextThemeWrapper; -import android.view.LayoutInflater; -import android.view.View; -import android.view.Window; -import android.view.accessibility.AccessibilityEvent; -import android.widget.SpinnerAdapter; -import com.actionbarsherlock.R; -import com.actionbarsherlock.app.ActionBar; -import com.actionbarsherlock.app.SherlockFragmentActivity; -import com.actionbarsherlock.internal.nineoldandroids.animation.Animator; -import com.actionbarsherlock.internal.nineoldandroids.animation.AnimatorListenerAdapter; -import com.actionbarsherlock.internal.nineoldandroids.animation.AnimatorSet; -import com.actionbarsherlock.internal.nineoldandroids.animation.ObjectAnimator; -import com.actionbarsherlock.internal.nineoldandroids.animation.Animator.AnimatorListener; -import com.actionbarsherlock.internal.nineoldandroids.widget.NineFrameLayout; -import com.actionbarsherlock.internal.view.menu.MenuBuilder; -import com.actionbarsherlock.internal.view.menu.MenuPopupHelper; -import com.actionbarsherlock.internal.view.menu.SubMenuBuilder; -import com.actionbarsherlock.internal.widget.ActionBarContainer; -import com.actionbarsherlock.internal.widget.ActionBarContextView; -import com.actionbarsherlock.internal.widget.ActionBarView; -import com.actionbarsherlock.internal.widget.ScrollingTabContainerView; -import com.actionbarsherlock.view.ActionMode; -import com.actionbarsherlock.view.Menu; -import com.actionbarsherlock.view.MenuInflater; -import com.actionbarsherlock.view.MenuItem; -import static com.actionbarsherlock.internal.ResourcesCompat.getResources_getBoolean; - -/** - * ActionBarImpl is the ActionBar implementation used - * by devices of all screen sizes. If it detects a compatible decor, - * it will split contextual modes across both the ActionBarView at - * the top of the screen and a horizontal LinearLayout at the bottom - * which is normally hidden. - */ -public class ActionBarImpl extends ActionBar { - //UNUSED private static final String TAG = "ActionBarImpl"; - - private Context mContext; - private Context mThemedContext; - private Activity mActivity; - //UNUSED private Dialog mDialog; - - private ActionBarContainer mContainerView; - private ActionBarView mActionView; - private ActionBarContextView mContextView; - private ActionBarContainer mSplitView; - private NineFrameLayout mContentView; - private ScrollingTabContainerView mTabScrollView; - - private ArrayList mTabs = new ArrayList(); - - private TabImpl mSelectedTab; - private int mSavedTabPosition = INVALID_POSITION; - - ActionModeImpl mActionMode; - ActionMode mDeferredDestroyActionMode; - ActionMode.Callback mDeferredModeDestroyCallback; - - private boolean mLastMenuVisibility; - private ArrayList mMenuVisibilityListeners = - new ArrayList(); - - private static final int CONTEXT_DISPLAY_NORMAL = 0; - private static final int CONTEXT_DISPLAY_SPLIT = 1; - - private static final int INVALID_POSITION = -1; - - private int mContextDisplayMode; - private boolean mHasEmbeddedTabs; - - final Handler mHandler = new Handler(); - Runnable mTabSelector; - - private Animator mCurrentShowAnim; - private Animator mCurrentModeAnim; - private boolean mShowHideAnimationEnabled; - boolean mWasHiddenBeforeMode; - - final AnimatorListener mHideListener = new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - if (mContentView != null) { - mContentView.setTranslationY(0); - mContainerView.setTranslationY(0); - } - if (mSplitView != null && mContextDisplayMode == CONTEXT_DISPLAY_SPLIT) { - mSplitView.setVisibility(View.GONE); - } - mContainerView.setVisibility(View.GONE); - mContainerView.setTransitioning(false); - mCurrentShowAnim = null; - completeDeferredDestroyActionMode(); - } - }; - - final AnimatorListener mShowListener = new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - mCurrentShowAnim = null; - mContainerView.requestLayout(); - } - }; - - public ActionBarImpl(Activity activity, int features) { - mActivity = activity; - Window window = activity.getWindow(); - View decor = window.getDecorView(); - init(decor); - - //window.hasFeature() workaround for pre-3.0 - if ((features & (1 << Window.FEATURE_ACTION_BAR_OVERLAY)) == 0) { - mContentView = (NineFrameLayout)decor.findViewById(android.R.id.content); - } - } - - public ActionBarImpl(Dialog dialog) { - //UNUSED mDialog = dialog; - init(dialog.getWindow().getDecorView()); - } - - private void init(View decor) { - mContext = decor.getContext(); - mActionView = (ActionBarView) decor.findViewById(R.id.abs__action_bar); - mContextView = (ActionBarContextView) decor.findViewById( - R.id.abs__action_context_bar); - mContainerView = (ActionBarContainer) decor.findViewById( - R.id.abs__action_bar_container); - mSplitView = (ActionBarContainer) decor.findViewById( - R.id.abs__split_action_bar); - - if (mActionView == null || mContextView == null || mContainerView == null) { - throw new IllegalStateException(getClass().getSimpleName() + " can only be used " + - "with a compatible window decor layout"); - } - - mActionView.setContextView(mContextView); - mContextDisplayMode = mActionView.isSplitActionBar() ? - CONTEXT_DISPLAY_SPLIT : CONTEXT_DISPLAY_NORMAL; - - // Older apps get the home button interaction enabled by default. - // Newer apps need to enable it explicitly. - setHomeButtonEnabled(mContext.getApplicationInfo().targetSdkVersion < 14); - - setHasEmbeddedTabs(getResources_getBoolean(mContext, - R.bool.abs__action_bar_embed_tabs)); - } - - public void onConfigurationChanged(Configuration newConfig) { - setHasEmbeddedTabs(getResources_getBoolean(mContext, - R.bool.abs__action_bar_embed_tabs)); - - //Manually dispatch a configuration change to the action bar view on pre-2.2 - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO) { - mActionView.onConfigurationChanged(newConfig); - if (mContextView != null) { - mContextView.onConfigurationChanged(newConfig); - } - } - } - - private void setHasEmbeddedTabs(boolean hasEmbeddedTabs) { - mHasEmbeddedTabs = hasEmbeddedTabs; - // Switch tab layout configuration if needed - if (!mHasEmbeddedTabs) { - mActionView.setEmbeddedTabView(null); - mContainerView.setTabContainer(mTabScrollView); - } else { - mContainerView.setTabContainer(null); - mActionView.setEmbeddedTabView(mTabScrollView); - } - final boolean isInTabMode = getNavigationMode() == NAVIGATION_MODE_TABS; - if (mTabScrollView != null) { - mTabScrollView.setVisibility(isInTabMode ? View.VISIBLE : View.GONE); - } - mActionView.setCollapsable(!mHasEmbeddedTabs && isInTabMode); - } - - private void ensureTabsExist() { - if (mTabScrollView != null) { - return; - } - - ScrollingTabContainerView tabScroller = new ScrollingTabContainerView(mContext); - - if (mHasEmbeddedTabs) { - tabScroller.setVisibility(View.VISIBLE); - mActionView.setEmbeddedTabView(tabScroller); - } else { - tabScroller.setVisibility(getNavigationMode() == NAVIGATION_MODE_TABS ? - View.VISIBLE : View.GONE); - mContainerView.setTabContainer(tabScroller); - } - mTabScrollView = tabScroller; - } - - void completeDeferredDestroyActionMode() { - if (mDeferredModeDestroyCallback != null) { - mDeferredModeDestroyCallback.onDestroyActionMode(mDeferredDestroyActionMode); - mDeferredDestroyActionMode = null; - mDeferredModeDestroyCallback = null; - } - } - - /** - * Enables or disables animation between show/hide states. - * If animation is disabled using this method, animations in progress - * will be finished. - * - * @param enabled true to animate, false to not animate. - */ - public void setShowHideAnimationEnabled(boolean enabled) { - mShowHideAnimationEnabled = enabled; - if (!enabled && mCurrentShowAnim != null) { - mCurrentShowAnim.end(); - } - } - - public void addOnMenuVisibilityListener(OnMenuVisibilityListener listener) { - mMenuVisibilityListeners.add(listener); - } - - public void removeOnMenuVisibilityListener(OnMenuVisibilityListener listener) { - mMenuVisibilityListeners.remove(listener); - } - - public void dispatchMenuVisibilityChanged(boolean isVisible) { - if (isVisible == mLastMenuVisibility) { - return; - } - mLastMenuVisibility = isVisible; - - final int count = mMenuVisibilityListeners.size(); - for (int i = 0; i < count; i++) { - mMenuVisibilityListeners.get(i).onMenuVisibilityChanged(isVisible); - } - } - - @Override - public void setCustomView(int resId) { - setCustomView(LayoutInflater.from(getThemedContext()).inflate(resId, mActionView, false)); - } - - @Override - public void setDisplayUseLogoEnabled(boolean useLogo) { - setDisplayOptions(useLogo ? DISPLAY_USE_LOGO : 0, DISPLAY_USE_LOGO); - } - - @Override - public void setDisplayShowHomeEnabled(boolean showHome) { - setDisplayOptions(showHome ? DISPLAY_SHOW_HOME : 0, DISPLAY_SHOW_HOME); - } - - @Override - public void setDisplayHomeAsUpEnabled(boolean showHomeAsUp) { - setDisplayOptions(showHomeAsUp ? DISPLAY_HOME_AS_UP : 0, DISPLAY_HOME_AS_UP); - } - - @Override - public void setDisplayShowTitleEnabled(boolean showTitle) { - setDisplayOptions(showTitle ? DISPLAY_SHOW_TITLE : 0, DISPLAY_SHOW_TITLE); - } - - @Override - public void setDisplayShowCustomEnabled(boolean showCustom) { - setDisplayOptions(showCustom ? DISPLAY_SHOW_CUSTOM : 0, DISPLAY_SHOW_CUSTOM); - } - - @Override - public void setHomeButtonEnabled(boolean enable) { - mActionView.setHomeButtonEnabled(enable); - } - - @Override - public void setTitle(int resId) { - setTitle(mContext.getString(resId)); - } - - @Override - public void setSubtitle(int resId) { - setSubtitle(mContext.getString(resId)); - } - - public void setSelectedNavigationItem(int position) { - switch (mActionView.getNavigationMode()) { - case NAVIGATION_MODE_TABS: - selectTab(mTabs.get(position)); - break; - case NAVIGATION_MODE_LIST: - mActionView.setDropdownSelectedPosition(position); - break; - default: - throw new IllegalStateException( - "setSelectedNavigationIndex not valid for current navigation mode"); - } - } - - public void removeAllTabs() { - cleanupTabs(); - } - - private void cleanupTabs() { - if (mSelectedTab != null) { - selectTab(null); - } - mTabs.clear(); - if (mTabScrollView != null) { - mTabScrollView.removeAllTabs(); - } - mSavedTabPosition = INVALID_POSITION; - } - - public void setTitle(CharSequence title) { - mActionView.setTitle(title); - } - - public void setSubtitle(CharSequence subtitle) { - mActionView.setSubtitle(subtitle); - } - - public void setDisplayOptions(int options) { - mActionView.setDisplayOptions(options); - } - - public void setDisplayOptions(int options, int mask) { - final int current = mActionView.getDisplayOptions(); - mActionView.setDisplayOptions((options & mask) | (current & ~mask)); - } - - public void setBackgroundDrawable(Drawable d) { - mContainerView.setPrimaryBackground(d); - } - - public void setStackedBackgroundDrawable(Drawable d) { - mContainerView.setStackedBackground(d); - } - - public void setSplitBackgroundDrawable(Drawable d) { - if (mSplitView != null) { - mSplitView.setSplitBackground(d); - } - } - - public View getCustomView() { - return mActionView.getCustomNavigationView(); - } - - public CharSequence getTitle() { - return mActionView.getTitle(); - } - - public CharSequence getSubtitle() { - return mActionView.getSubtitle(); - } - - public int getNavigationMode() { - return mActionView.getNavigationMode(); - } - - public int getDisplayOptions() { - return mActionView.getDisplayOptions(); - } - - public ActionMode startActionMode(ActionMode.Callback callback) { - boolean wasHidden = false; - if (mActionMode != null) { - wasHidden = mWasHiddenBeforeMode; - mActionMode.finish(); - } - - mContextView.killMode(); - ActionModeImpl mode = new ActionModeImpl(callback); - if (mode.dispatchOnCreate()) { - mWasHiddenBeforeMode = !isShowing() || wasHidden; - mode.invalidate(); - mContextView.initForMode(mode); - animateToMode(true); - if (mSplitView != null && mContextDisplayMode == CONTEXT_DISPLAY_SPLIT) { - // TODO animate this - mSplitView.setVisibility(View.VISIBLE); - } - mContextView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); - mActionMode = mode; - return mode; - } - return null; - } - - private void configureTab(Tab tab, int position) { - final TabImpl tabi = (TabImpl) tab; - final ActionBar.TabListener callback = tabi.getCallback(); - - if (callback == null) { - throw new IllegalStateException("Action Bar Tab must have a Callback"); - } - - tabi.setPosition(position); - mTabs.add(position, tabi); - - final int count = mTabs.size(); - for (int i = position + 1; i < count; i++) { - mTabs.get(i).setPosition(i); - } - } - - @Override - public void addTab(Tab tab) { - addTab(tab, mTabs.isEmpty()); - } - - @Override - public void addTab(Tab tab, int position) { - addTab(tab, position, mTabs.isEmpty()); - } - - @Override - public void addTab(Tab tab, boolean setSelected) { - ensureTabsExist(); - mTabScrollView.addTab(tab, setSelected); - configureTab(tab, mTabs.size()); - if (setSelected) { - selectTab(tab); - } - } - - @Override - public void addTab(Tab tab, int position, boolean setSelected) { - ensureTabsExist(); - mTabScrollView.addTab(tab, position, setSelected); - configureTab(tab, position); - if (setSelected) { - selectTab(tab); - } - } - - @Override - public Tab newTab() { - return new TabImpl(); - } - - @Override - public void removeTab(Tab tab) { - removeTabAt(tab.getPosition()); - } - - @Override - public void removeTabAt(int position) { - if (mTabScrollView == null) { - // No tabs around to remove - return; - } - - int selectedTabPosition = mSelectedTab != null - ? mSelectedTab.getPosition() : mSavedTabPosition; - mTabScrollView.removeTabAt(position); - TabImpl removedTab = mTabs.remove(position); - if (removedTab != null) { - removedTab.setPosition(-1); - } - - final int newTabCount = mTabs.size(); - for (int i = position; i < newTabCount; i++) { - mTabs.get(i).setPosition(i); - } - - if (selectedTabPosition == position) { - selectTab(mTabs.isEmpty() ? null : mTabs.get(Math.max(0, position - 1))); - } - } - - @Override - public void selectTab(Tab tab) { - if (getNavigationMode() != NAVIGATION_MODE_TABS) { - mSavedTabPosition = tab != null ? tab.getPosition() : INVALID_POSITION; - return; - } - - FragmentTransaction trans = null; - if (mActivity instanceof SherlockFragmentActivity) { - trans = ((SherlockFragmentActivity)mActivity).getSupportFragmentManager().beginTransaction() - .disallowAddToBackStack(); - } - - if (mSelectedTab == tab) { - if (mSelectedTab != null) { - mSelectedTab.getCallback().onTabReselected(mSelectedTab, trans); - mTabScrollView.animateToTab(tab.getPosition()); - } - } else { - mTabScrollView.setTabSelected(tab != null ? tab.getPosition() : Tab.INVALID_POSITION); - if (mSelectedTab != null) { - mSelectedTab.getCallback().onTabUnselected(mSelectedTab, trans); - } - mSelectedTab = (TabImpl) tab; - if (mSelectedTab != null) { - mSelectedTab.getCallback().onTabSelected(mSelectedTab, trans); - } - } - - if (trans != null && !trans.isEmpty()) { - trans.commit(); - } - } - - @Override - public Tab getSelectedTab() { - return mSelectedTab; - } - - @Override - public int getHeight() { - return mContainerView.getHeight(); - } - - @Override - public void show() { - show(true); - } - - void show(boolean markHiddenBeforeMode) { - if (mCurrentShowAnim != null) { - mCurrentShowAnim.end(); - } - if (mContainerView.getVisibility() == View.VISIBLE) { - if (markHiddenBeforeMode) mWasHiddenBeforeMode = false; - return; - } - mContainerView.setVisibility(View.VISIBLE); - - if (mShowHideAnimationEnabled) { - mContainerView.setAlpha(0); - AnimatorSet anim = new AnimatorSet(); - AnimatorSet.Builder b = anim.play(ObjectAnimator.ofFloat(mContainerView, "alpha", 1)); - if (mContentView != null) { - b.with(ObjectAnimator.ofFloat(mContentView, "translationY", - -mContainerView.getHeight(), 0)); - mContainerView.setTranslationY(-mContainerView.getHeight()); - b.with(ObjectAnimator.ofFloat(mContainerView, "translationY", 0)); - } - if (mSplitView != null && mContextDisplayMode == CONTEXT_DISPLAY_SPLIT) { - mSplitView.setAlpha(0); - mSplitView.setVisibility(View.VISIBLE); - b.with(ObjectAnimator.ofFloat(mSplitView, "alpha", 1)); - } - anim.addListener(mShowListener); - mCurrentShowAnim = anim; - anim.start(); - } else { - mContainerView.setAlpha(1); - mContainerView.setTranslationY(0); - mShowListener.onAnimationEnd(null); - } - } - - @Override - public void hide() { - if (mCurrentShowAnim != null) { - mCurrentShowAnim.end(); - } - if (mContainerView.getVisibility() == View.GONE) { - return; - } - - if (mShowHideAnimationEnabled) { - mContainerView.setAlpha(1); - mContainerView.setTransitioning(true); - AnimatorSet anim = new AnimatorSet(); - AnimatorSet.Builder b = anim.play(ObjectAnimator.ofFloat(mContainerView, "alpha", 0)); - if (mContentView != null) { - b.with(ObjectAnimator.ofFloat(mContentView, "translationY", - 0, -mContainerView.getHeight())); - b.with(ObjectAnimator.ofFloat(mContainerView, "translationY", - -mContainerView.getHeight())); - } - if (mSplitView != null && mSplitView.getVisibility() == View.VISIBLE) { - mSplitView.setAlpha(1); - b.with(ObjectAnimator.ofFloat(mSplitView, "alpha", 0)); - } - anim.addListener(mHideListener); - mCurrentShowAnim = anim; - anim.start(); - } else { - mHideListener.onAnimationEnd(null); - } - } - - public boolean isShowing() { - return mContainerView.getVisibility() == View.VISIBLE; - } - - void animateToMode(boolean toActionMode) { - if (toActionMode) { - show(false); - } - if (mCurrentModeAnim != null) { - mCurrentModeAnim.end(); - } - - mActionView.animateToVisibility(toActionMode ? View.GONE : View.VISIBLE); - mContextView.animateToVisibility(toActionMode ? View.VISIBLE : View.GONE); - if (mTabScrollView != null && !mActionView.hasEmbeddedTabs() && mActionView.isCollapsed()) { - mTabScrollView.animateToVisibility(toActionMode ? View.GONE : View.VISIBLE); - } - } - - public Context getThemedContext() { - if (mThemedContext == null) { - TypedValue outValue = new TypedValue(); - Resources.Theme currentTheme = mContext.getTheme(); - currentTheme.resolveAttribute(R.attr.actionBarWidgetTheme, - outValue, true); - final int targetThemeRes = outValue.resourceId; - - if (targetThemeRes != 0) { //XXX && mContext.getThemeResId() != targetThemeRes) { - mThemedContext = new ContextThemeWrapper(mContext, targetThemeRes); - } else { - mThemedContext = mContext; - } - } - return mThemedContext; - } - - /** - * @hide - */ - public class ActionModeImpl extends ActionMode implements MenuBuilder.Callback { - private ActionMode.Callback mCallback; - private MenuBuilder mMenu; - private WeakReference mCustomView; - - public ActionModeImpl(ActionMode.Callback callback) { - mCallback = callback; - mMenu = new MenuBuilder(getThemedContext()) - .setDefaultShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); - mMenu.setCallback(this); - } - - @Override - public MenuInflater getMenuInflater() { - return new MenuInflater(getThemedContext()); - } - - @Override - public Menu getMenu() { - return mMenu; - } - - @Override - public void finish() { - if (mActionMode != this) { - // Not the active action mode - no-op - return; - } - - // If we were hidden before the mode was shown, defer the onDestroy - // callback until the animation is finished and associated relayout - // is about to happen. This lets apps better anticipate visibility - // and layout behavior. - if (mWasHiddenBeforeMode) { - mDeferredDestroyActionMode = this; - mDeferredModeDestroyCallback = mCallback; - } else { - mCallback.onDestroyActionMode(this); - } - mCallback = null; - animateToMode(false); - - // Clear out the context mode views after the animation finishes - mContextView.closeMode(); - mActionView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); - - mActionMode = null; - - if (mWasHiddenBeforeMode) { - hide(); - } - } - - @Override - public void invalidate() { - mMenu.stopDispatchingItemsChanged(); - try { - mCallback.onPrepareActionMode(this, mMenu); - } finally { - mMenu.startDispatchingItemsChanged(); - } - } - - public boolean dispatchOnCreate() { - mMenu.stopDispatchingItemsChanged(); - try { - return mCallback.onCreateActionMode(this, mMenu); - } finally { - mMenu.startDispatchingItemsChanged(); - } - } - - @Override - public void setCustomView(View view) { - mContextView.setCustomView(view); - mCustomView = new WeakReference(view); - } - - @Override - public void setSubtitle(CharSequence subtitle) { - mContextView.setSubtitle(subtitle); - } - - @Override - public void setTitle(CharSequence title) { - mContextView.setTitle(title); - } - - @Override - public void setTitle(int resId) { - setTitle(mContext.getResources().getString(resId)); - } - - @Override - public void setSubtitle(int resId) { - setSubtitle(mContext.getResources().getString(resId)); - } - - @Override - public CharSequence getTitle() { - return mContextView.getTitle(); - } - - @Override - public CharSequence getSubtitle() { - return mContextView.getSubtitle(); - } - - @Override - public View getCustomView() { - return mCustomView != null ? mCustomView.get() : null; - } - - public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) { - if (mCallback != null) { - return mCallback.onActionItemClicked(this, item); - } else { - return false; - } - } - - public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) { - } - - public boolean onSubMenuSelected(SubMenuBuilder subMenu) { - if (mCallback == null) { - return false; - } - - if (!subMenu.hasVisibleItems()) { - return true; - } - - new MenuPopupHelper(getThemedContext(), subMenu).show(); - return true; - } - - public void onCloseSubMenu(SubMenuBuilder menu) { - } - - public void onMenuModeChange(MenuBuilder menu) { - if (mCallback == null) { - return; - } - invalidate(); - mContextView.showOverflowMenu(); - } - } - - /** - * @hide - */ - public class TabImpl extends ActionBar.Tab { - private ActionBar.TabListener mCallback; - private Object mTag; - private Drawable mIcon; - private CharSequence mText; - private CharSequence mContentDesc; - private int mPosition = -1; - private View mCustomView; - - @Override - public Object getTag() { - return mTag; - } - - @Override - public Tab setTag(Object tag) { - mTag = tag; - return this; - } - - public ActionBar.TabListener getCallback() { - return mCallback; - } - - @Override - public Tab setTabListener(ActionBar.TabListener callback) { - mCallback = callback; - return this; - } - - @Override - public View getCustomView() { - return mCustomView; - } - - @Override - public Tab setCustomView(View view) { - mCustomView = view; - if (mPosition >= 0) { - mTabScrollView.updateTab(mPosition); - } - return this; - } - - @Override - public Tab setCustomView(int layoutResId) { - return setCustomView(LayoutInflater.from(getThemedContext()) - .inflate(layoutResId, null)); - } - - @Override - public Drawable getIcon() { - return mIcon; - } - - @Override - public int getPosition() { - return mPosition; - } - - public void setPosition(int position) { - mPosition = position; - } - - @Override - public CharSequence getText() { - return mText; - } - - @Override - public Tab setIcon(Drawable icon) { - mIcon = icon; - if (mPosition >= 0) { - mTabScrollView.updateTab(mPosition); - } - return this; - } - - @Override - public Tab setIcon(int resId) { - return setIcon(mContext.getResources().getDrawable(resId)); - } - - @Override - public Tab setText(CharSequence text) { - mText = text; - if (mPosition >= 0) { - mTabScrollView.updateTab(mPosition); - } - return this; - } - - @Override - public Tab setText(int resId) { - return setText(mContext.getResources().getText(resId)); - } - - @Override - public void select() { - selectTab(this); - } - - @Override - public Tab setContentDescription(int resId) { - return setContentDescription(mContext.getResources().getText(resId)); - } - - @Override - public Tab setContentDescription(CharSequence contentDesc) { - mContentDesc = contentDesc; - if (mPosition >= 0) { - mTabScrollView.updateTab(mPosition); - } - return this; - } - - @Override - public CharSequence getContentDescription() { - return mContentDesc; - } - } - - @Override - public void setCustomView(View view) { - mActionView.setCustomNavigationView(view); - } - - @Override - public void setCustomView(View view, LayoutParams layoutParams) { - view.setLayoutParams(layoutParams); - mActionView.setCustomNavigationView(view); - } - - @Override - public void setListNavigationCallbacks(SpinnerAdapter adapter, OnNavigationListener callback) { - mActionView.setDropdownAdapter(adapter); - mActionView.setCallback(callback); - } - - @Override - public int getSelectedNavigationIndex() { - switch (mActionView.getNavigationMode()) { - case NAVIGATION_MODE_TABS: - return mSelectedTab != null ? mSelectedTab.getPosition() : -1; - case NAVIGATION_MODE_LIST: - return mActionView.getDropdownSelectedPosition(); - default: - return -1; - } - } - - @Override - public int getNavigationItemCount() { - switch (mActionView.getNavigationMode()) { - case NAVIGATION_MODE_TABS: - return mTabs.size(); - case NAVIGATION_MODE_LIST: - SpinnerAdapter adapter = mActionView.getDropdownAdapter(); - return adapter != null ? adapter.getCount() : 0; - default: - return 0; - } - } - - @Override - public int getTabCount() { - return mTabs.size(); - } - - @Override - public void setNavigationMode(int mode) { - final int oldMode = mActionView.getNavigationMode(); - switch (oldMode) { - case NAVIGATION_MODE_TABS: - mSavedTabPosition = getSelectedNavigationIndex(); - selectTab(null); - mTabScrollView.setVisibility(View.GONE); - break; - } - mActionView.setNavigationMode(mode); - switch (mode) { - case NAVIGATION_MODE_TABS: - ensureTabsExist(); - mTabScrollView.setVisibility(View.VISIBLE); - if (mSavedTabPosition != INVALID_POSITION) { - setSelectedNavigationItem(mSavedTabPosition); - mSavedTabPosition = INVALID_POSITION; - } - break; - } - mActionView.setCollapsable(mode == NAVIGATION_MODE_TABS && !mHasEmbeddedTabs); - } - - @Override - public Tab getTabAt(int index) { - return mTabs.get(index); - } - - - @Override - public void setIcon(int resId) { - mActionView.setIcon(resId); - } - - @Override - public void setIcon(Drawable icon) { - mActionView.setIcon(icon); - } - - @Override - public void setLogo(int resId) { - mActionView.setLogo(resId); - } - - @Override - public void setLogo(Drawable logo) { - mActionView.setLogo(logo); - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/app/ActionBarWrapper.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/app/ActionBarWrapper.java deleted file mode 100644 index e390ea428..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/app/ActionBarWrapper.java +++ /dev/null @@ -1,468 +0,0 @@ -package com.actionbarsherlock.internal.app; - -import java.util.HashSet; -import java.util.Set; - -import android.app.Activity; -import android.content.Context; -import android.graphics.drawable.Drawable; -import android.support.v4.app.FragmentTransaction; -import android.view.View; -import android.widget.SpinnerAdapter; - -import com.actionbarsherlock.app.ActionBar; -import com.actionbarsherlock.app.SherlockFragmentActivity; - -public class ActionBarWrapper extends ActionBar implements android.app.ActionBar.OnNavigationListener, android.app.ActionBar.OnMenuVisibilityListener { - private final Activity mActivity; - private final android.app.ActionBar mActionBar; - private ActionBar.OnNavigationListener mNavigationListener; - private Set mMenuVisibilityListeners = new HashSet(1); - private FragmentTransaction mFragmentTransaction; - - - public ActionBarWrapper(Activity activity) { - mActivity = activity; - mActionBar = activity.getActionBar(); - if (mActionBar != null) { - mActionBar.addOnMenuVisibilityListener(this); - } - } - - - @Override - public void setHomeButtonEnabled(boolean enabled) { - mActionBar.setHomeButtonEnabled(enabled); - } - - @Override - public Context getThemedContext() { - return mActionBar.getThemedContext(); - } - - @Override - public void setCustomView(View view) { - mActionBar.setCustomView(view); - } - - @Override - public void setCustomView(View view, LayoutParams layoutParams) { - android.app.ActionBar.LayoutParams lp = new android.app.ActionBar.LayoutParams(layoutParams); - lp.gravity = layoutParams.gravity; - lp.bottomMargin = layoutParams.bottomMargin; - lp.topMargin = layoutParams.topMargin; - lp.leftMargin = layoutParams.leftMargin; - lp.rightMargin = layoutParams.rightMargin; - mActionBar.setCustomView(view, lp); - } - - @Override - public void setCustomView(int resId) { - mActionBar.setCustomView(resId); - } - - @Override - public void setIcon(int resId) { - mActionBar.setIcon(resId); - } - - @Override - public void setIcon(Drawable icon) { - mActionBar.setIcon(icon); - } - - @Override - public void setLogo(int resId) { - mActionBar.setLogo(resId); - } - - @Override - public void setLogo(Drawable logo) { - mActionBar.setLogo(logo); - } - - @Override - public void setListNavigationCallbacks(SpinnerAdapter adapter, OnNavigationListener callback) { - mNavigationListener = callback; - mActionBar.setListNavigationCallbacks(adapter, (callback != null) ? this : null); - } - - @Override - public boolean onNavigationItemSelected(int itemPosition, long itemId) { - //This should never be a NullPointerException since we only set - //ourselves as the listener when the callback is not null. - return mNavigationListener.onNavigationItemSelected(itemPosition, itemId); - } - - @Override - public void setSelectedNavigationItem(int position) { - mActionBar.setSelectedNavigationItem(position); - } - - @Override - public int getSelectedNavigationIndex() { - return mActionBar.getSelectedNavigationIndex(); - } - - @Override - public int getNavigationItemCount() { - return mActionBar.getNavigationItemCount(); - } - - @Override - public void setTitle(CharSequence title) { - mActionBar.setTitle(title); - } - - @Override - public void setTitle(int resId) { - mActionBar.setTitle(resId); - } - - @Override - public void setSubtitle(CharSequence subtitle) { - mActionBar.setSubtitle(subtitle); - } - - @Override - public void setSubtitle(int resId) { - mActionBar.setSubtitle(resId); - } - - @Override - public void setDisplayOptions(int options) { - mActionBar.setDisplayOptions(options); - } - - @Override - public void setDisplayOptions(int options, int mask) { - mActionBar.setDisplayOptions(options, mask); - } - - @Override - public void setDisplayUseLogoEnabled(boolean useLogo) { - mActionBar.setDisplayUseLogoEnabled(useLogo); - } - - @Override - public void setDisplayShowHomeEnabled(boolean showHome) { - mActionBar.setDisplayShowHomeEnabled(showHome); - } - - @Override - public void setDisplayHomeAsUpEnabled(boolean showHomeAsUp) { - mActionBar.setDisplayHomeAsUpEnabled(showHomeAsUp); - } - - @Override - public void setDisplayShowTitleEnabled(boolean showTitle) { - mActionBar.setDisplayShowTitleEnabled(showTitle); - } - - @Override - public void setDisplayShowCustomEnabled(boolean showCustom) { - mActionBar.setDisplayShowCustomEnabled(showCustom); - } - - @Override - public void setBackgroundDrawable(Drawable d) { - mActionBar.setBackgroundDrawable(d); - } - - @Override - public void setStackedBackgroundDrawable(Drawable d) { - mActionBar.setStackedBackgroundDrawable(d); - } - - @Override - public void setSplitBackgroundDrawable(Drawable d) { - mActionBar.setSplitBackgroundDrawable(d); - } - - @Override - public View getCustomView() { - return mActionBar.getCustomView(); - } - - @Override - public CharSequence getTitle() { - return mActionBar.getTitle(); - } - - @Override - public CharSequence getSubtitle() { - return mActionBar.getSubtitle(); - } - - @Override - public int getNavigationMode() { - return mActionBar.getNavigationMode(); - } - - @Override - public void setNavigationMode(int mode) { - mActionBar.setNavigationMode(mode); - } - - @Override - public int getDisplayOptions() { - return mActionBar.getDisplayOptions(); - } - - public class TabWrapper extends ActionBar.Tab implements android.app.ActionBar.TabListener { - final android.app.ActionBar.Tab mNativeTab; - private Object mTag; - private TabListener mListener; - - public TabWrapper(android.app.ActionBar.Tab nativeTab) { - mNativeTab = nativeTab; - mNativeTab.setTag(this); - } - - @Override - public int getPosition() { - return mNativeTab.getPosition(); - } - - @Override - public Drawable getIcon() { - return mNativeTab.getIcon(); - } - - @Override - public CharSequence getText() { - return mNativeTab.getText(); - } - - @Override - public Tab setIcon(Drawable icon) { - mNativeTab.setIcon(icon); - return this; - } - - @Override - public Tab setIcon(int resId) { - mNativeTab.setIcon(resId); - return this; - } - - @Override - public Tab setText(CharSequence text) { - mNativeTab.setText(text); - return this; - } - - @Override - public Tab setText(int resId) { - mNativeTab.setText(resId); - return this; - } - - @Override - public Tab setCustomView(View view) { - mNativeTab.setCustomView(view); - return this; - } - - @Override - public Tab setCustomView(int layoutResId) { - mNativeTab.setCustomView(layoutResId); - return this; - } - - @Override - public View getCustomView() { - return mNativeTab.getCustomView(); - } - - @Override - public Tab setTag(Object obj) { - mTag = obj; - return this; - } - - @Override - public Object getTag() { - return mTag; - } - - @Override - public Tab setTabListener(TabListener listener) { - mNativeTab.setTabListener(listener != null ? this : null); - mListener = listener; - return this; - } - - @Override - public void select() { - mNativeTab.select(); - } - - @Override - public Tab setContentDescription(int resId) { - mNativeTab.setContentDescription(resId); - return this; - } - - @Override - public Tab setContentDescription(CharSequence contentDesc) { - mNativeTab.setContentDescription(contentDesc); - return this; - } - - @Override - public CharSequence getContentDescription() { - return mNativeTab.getContentDescription(); - } - - @Override - public void onTabReselected(android.app.ActionBar.Tab tab, android.app.FragmentTransaction ft) { - if (mListener != null) { - FragmentTransaction trans = null; - if (mActivity instanceof SherlockFragmentActivity) { - trans = ((SherlockFragmentActivity)mActivity).getSupportFragmentManager().beginTransaction() - .disallowAddToBackStack(); - } - - mListener.onTabReselected(this, trans); - - if (trans != null && !trans.isEmpty()) { - trans.commit(); - } - } - } - - @Override - public void onTabSelected(android.app.ActionBar.Tab tab, android.app.FragmentTransaction ft) { - if (mListener != null) { - - if (mFragmentTransaction == null && mActivity instanceof SherlockFragmentActivity) { - mFragmentTransaction = ((SherlockFragmentActivity)mActivity).getSupportFragmentManager().beginTransaction() - .disallowAddToBackStack(); - } - - mListener.onTabSelected(this, mFragmentTransaction); - - if (mFragmentTransaction != null) { - if (!mFragmentTransaction.isEmpty()) { - mFragmentTransaction.commit(); - } - mFragmentTransaction = null; - } - } - } - - @Override - public void onTabUnselected(android.app.ActionBar.Tab tab, android.app.FragmentTransaction ft) { - if (mListener != null) { - FragmentTransaction trans = null; - if (mActivity instanceof SherlockFragmentActivity) { - trans = ((SherlockFragmentActivity)mActivity).getSupportFragmentManager().beginTransaction() - .disallowAddToBackStack(); - mFragmentTransaction = trans; - } - - mListener.onTabUnselected(this, trans); - } - } - } - - @Override - public Tab newTab() { - return new TabWrapper(mActionBar.newTab()); - } - - @Override - public void addTab(Tab tab) { - mActionBar.addTab(((TabWrapper)tab).mNativeTab); - } - - @Override - public void addTab(Tab tab, boolean setSelected) { - mActionBar.addTab(((TabWrapper)tab).mNativeTab, setSelected); - } - - @Override - public void addTab(Tab tab, int position) { - mActionBar.addTab(((TabWrapper)tab).mNativeTab, position); - } - - @Override - public void addTab(Tab tab, int position, boolean setSelected) { - mActionBar.addTab(((TabWrapper)tab).mNativeTab, position, setSelected); - } - - @Override - public void removeTab(Tab tab) { - mActionBar.removeTab(((TabWrapper)tab).mNativeTab); - } - - @Override - public void removeTabAt(int position) { - mActionBar.removeTabAt(position); - } - - @Override - public void removeAllTabs() { - mActionBar.removeAllTabs(); - } - - @Override - public void selectTab(Tab tab) { - mActionBar.selectTab(((TabWrapper)tab).mNativeTab); - } - - @Override - public Tab getSelectedTab() { - android.app.ActionBar.Tab selected = mActionBar.getSelectedTab(); - return (selected != null) ? (Tab)selected.getTag() : null; - } - - @Override - public Tab getTabAt(int index) { - android.app.ActionBar.Tab selected = mActionBar.getTabAt(index); - return (selected != null) ? (Tab)selected.getTag() : null; - } - - @Override - public int getTabCount() { - return mActionBar.getTabCount(); - } - - @Override - public int getHeight() { - return mActionBar.getHeight(); - } - - @Override - public void show() { - mActionBar.show(); - } - - @Override - public void hide() { - mActionBar.hide(); - } - - @Override - public boolean isShowing() { - return mActionBar.isShowing(); - } - - @Override - public void addOnMenuVisibilityListener(OnMenuVisibilityListener listener) { - mMenuVisibilityListeners.add(listener); - } - - @Override - public void removeOnMenuVisibilityListener(OnMenuVisibilityListener listener) { - mMenuVisibilityListeners.remove(listener); - } - - @Override - public void onMenuVisibilityChanged(boolean isVisible) { - for (OnMenuVisibilityListener listener : mMenuVisibilityListeners) { - listener.onMenuVisibilityChanged(isVisible); - } - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/Animator.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/Animator.java deleted file mode 100644 index 2caf5b4a9..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/Animator.java +++ /dev/null @@ -1,278 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.nineoldandroids.animation; - -import java.util.ArrayList; - -import android.view.animation.Interpolator; - -/** - * This is the superclass for classes which provide basic support for animations which can be - * started, ended, and have AnimatorListeners added to them. - */ -public abstract class Animator implements Cloneable { - - - /** - * The set of listeners to be sent events through the life of an animation. - */ - ArrayList mListeners = null; - - /** - * Starts this animation. If the animation has a nonzero startDelay, the animation will start - * running after that delay elapses. A non-delayed animation will have its initial - * value(s) set immediately, followed by calls to - * {@link AnimatorListener#onAnimationStart(Animator)} for any listeners of this animator. - * - *

The animation started by calling this method will be run on the thread that called - * this method. This thread should have a Looper on it (a runtime exception will be thrown if - * this is not the case). Also, if the animation will animate - * properties of objects in the view hierarchy, then the calling thread should be the UI - * thread for that view hierarchy.

- * - */ - public void start() { - } - - /** - * Cancels the animation. Unlike {@link #end()}, cancel() causes the animation to - * stop in its tracks, sending an - * {@link android.animation.Animator.AnimatorListener#onAnimationCancel(Animator)} to - * its listeners, followed by an - * {@link android.animation.Animator.AnimatorListener#onAnimationEnd(Animator)} message. - * - *

This method must be called on the thread that is running the animation.

- */ - public void cancel() { - } - - /** - * Ends the animation. This causes the animation to assign the end value of the property being - * animated, then calling the - * {@link android.animation.Animator.AnimatorListener#onAnimationEnd(Animator)} method on - * its listeners. - * - *

This method must be called on the thread that is running the animation.

- */ - public void end() { - } - - /** - * The amount of time, in milliseconds, to delay starting the animation after - * {@link #start()} is called. - * - * @return the number of milliseconds to delay running the animation - */ - public abstract long getStartDelay(); - - /** - * The amount of time, in milliseconds, to delay starting the animation after - * {@link #start()} is called. - - * @param startDelay The amount of the delay, in milliseconds - */ - public abstract void setStartDelay(long startDelay); - - - /** - * Sets the length of the animation. - * - * @param duration The length of the animation, in milliseconds. - */ - public abstract Animator setDuration(long duration); - - /** - * Gets the length of the animation. - * - * @return The length of the animation, in milliseconds. - */ - public abstract long getDuration(); - - /** - * The time interpolator used in calculating the elapsed fraction of this animation. The - * interpolator determines whether the animation runs with linear or non-linear motion, - * such as acceleration and deceleration. The default value is - * {@link android.view.animation.AccelerateDecelerateInterpolator} - * - * @param value the interpolator to be used by this animation - */ - public abstract void setInterpolator(/*Time*/Interpolator value); - - /** - * Returns whether this Animator is currently running (having been started and gone past any - * initial startDelay period and not yet ended). - * - * @return Whether the Animator is running. - */ - public abstract boolean isRunning(); - - /** - * Returns whether this Animator has been started and not yet ended. This state is a superset - * of the state of {@link #isRunning()}, because an Animator with a nonzero - * {@link #getStartDelay() startDelay} will return true for {@link #isStarted()} during the - * delay phase, whereas {@link #isRunning()} will return true only after the delay phase - * is complete. - * - * @return Whether the Animator has been started and not yet ended. - */ - public boolean isStarted() { - // Default method returns value for isRunning(). Subclasses should override to return a - // real value. - return isRunning(); - } - - /** - * Adds a listener to the set of listeners that are sent events through the life of an - * animation, such as start, repeat, and end. - * - * @param listener the listener to be added to the current set of listeners for this animation. - */ - public void addListener(AnimatorListener listener) { - if (mListeners == null) { - mListeners = new ArrayList(); - } - mListeners.add(listener); - } - - /** - * Removes a listener from the set listening to this animation. - * - * @param listener the listener to be removed from the current set of listeners for this - * animation. - */ - public void removeListener(AnimatorListener listener) { - if (mListeners == null) { - return; - } - mListeners.remove(listener); - if (mListeners.size() == 0) { - mListeners = null; - } - } - - /** - * Gets the set of {@link android.animation.Animator.AnimatorListener} objects that are currently - * listening for events on this Animator object. - * - * @return ArrayList The set of listeners. - */ - public ArrayList getListeners() { - return mListeners; - } - - /** - * Removes all listeners from this object. This is equivalent to calling - * getListeners() followed by calling clear() on the - * returned list of listeners. - */ - public void removeAllListeners() { - if (mListeners != null) { - mListeners.clear(); - mListeners = null; - } - } - - @Override - public Animator clone() { - try { - final Animator anim = (Animator) super.clone(); - if (mListeners != null) { - ArrayList oldListeners = mListeners; - anim.mListeners = new ArrayList(); - int numListeners = oldListeners.size(); - for (int i = 0; i < numListeners; ++i) { - anim.mListeners.add(oldListeners.get(i)); - } - } - return anim; - } catch (CloneNotSupportedException e) { - throw new AssertionError(); - } - } - - /** - * This method tells the object to use appropriate information to extract - * starting values for the animation. For example, a AnimatorSet object will pass - * this call to its child objects to tell them to set up the values. A - * ObjectAnimator object will use the information it has about its target object - * and PropertyValuesHolder objects to get the start values for its properties. - * An ValueAnimator object will ignore the request since it does not have enough - * information (such as a target object) to gather these values. - */ - public void setupStartValues() { - } - - /** - * This method tells the object to use appropriate information to extract - * ending values for the animation. For example, a AnimatorSet object will pass - * this call to its child objects to tell them to set up the values. A - * ObjectAnimator object will use the information it has about its target object - * and PropertyValuesHolder objects to get the start values for its properties. - * An ValueAnimator object will ignore the request since it does not have enough - * information (such as a target object) to gather these values. - */ - public void setupEndValues() { - } - - /** - * Sets the target object whose property will be animated by this animation. Not all subclasses - * operate on target objects (for example, {@link ValueAnimator}, but this method - * is on the superclass for the convenience of dealing generically with those subclasses - * that do handle targets. - * - * @param target The object being animated - */ - public void setTarget(Object target) { - } - - /** - *

An animation listener receives notifications from an animation. - * Notifications indicate animation related events, such as the end or the - * repetition of the animation.

- */ - public static interface AnimatorListener { - /** - *

Notifies the start of the animation.

- * - * @param animation The started animation. - */ - void onAnimationStart(Animator animation); - - /** - *

Notifies the end of the animation. This callback is not invoked - * for animations with repeat count set to INFINITE.

- * - * @param animation The animation which reached its end. - */ - void onAnimationEnd(Animator animation); - - /** - *

Notifies the cancellation of the animation. This callback is not invoked - * for animations with repeat count set to INFINITE.

- * - * @param animation The animation which was canceled. - */ - void onAnimationCancel(Animator animation); - - /** - *

Notifies the repetition of the animation.

- * - * @param animation The animation which was repeated. - */ - void onAnimationRepeat(Animator animation); - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/AnimatorListenerAdapter.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/AnimatorListenerAdapter.java deleted file mode 100644 index 02ddff48d..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/AnimatorListenerAdapter.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.nineoldandroids.animation; - -/** - * This adapter class provides empty implementations of the methods from {@link android.animation.Animator.AnimatorListener}. - * Any custom listener that cares only about a subset of the methods of this listener can - * simply subclass this adapter class instead of implementing the interface directly. - */ -public abstract class AnimatorListenerAdapter implements Animator.AnimatorListener { - - /** - * {@inheritDoc} - */ - @Override - public void onAnimationCancel(Animator animation) { - } - - /** - * {@inheritDoc} - */ - @Override - public void onAnimationEnd(Animator animation) { - } - - /** - * {@inheritDoc} - */ - @Override - public void onAnimationRepeat(Animator animation) { - } - - /** - * {@inheritDoc} - */ - @Override - public void onAnimationStart(Animator animation) { - } - -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/AnimatorSet.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/AnimatorSet.java deleted file mode 100644 index 3231080c4..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/AnimatorSet.java +++ /dev/null @@ -1,1111 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.nineoldandroids.animation; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; - -import android.view.animation.Interpolator; - -/** - * This class plays a set of {@link Animator} objects in the specified order. Animations - * can be set up to play together, in sequence, or after a specified delay. - * - *

There are two different approaches to adding animations to a AnimatorSet: - * either the {@link AnimatorSet#playTogether(Animator[]) playTogether()} or - * {@link AnimatorSet#playSequentially(Animator[]) playSequentially()} methods can be called to add - * a set of animations all at once, or the {@link AnimatorSet#play(Animator)} can be - * used in conjunction with methods in the {@link AnimatorSet.Builder Builder} - * class to add animations - * one by one.

- * - *

It is possible to set up a AnimatorSet with circular dependencies between - * its animations. For example, an animation a1 could be set up to start before animation a2, a2 - * before a3, and a3 before a1. The results of this configuration are undefined, but will typically - * result in none of the affected animations being played. Because of this (and because - * circular dependencies do not make logical sense anyway), circular dependencies - * should be avoided, and the dependency flow of animations should only be in one direction. - */ -@SuppressWarnings("unchecked") -public final class AnimatorSet extends Animator { - - /** - * Internal variables - * NOTE: This object implements the clone() method, making a deep copy of any referenced - * objects. As other non-trivial fields are added to this class, make sure to add logic - * to clone() to make deep copies of them. - */ - - /** - * Tracks animations currently being played, so that we know what to - * cancel or end when cancel() or end() is called on this AnimatorSet - */ - private ArrayList mPlayingSet = new ArrayList(); - - /** - * Contains all nodes, mapped to their respective Animators. When new - * dependency information is added for an Animator, we want to add it - * to a single node representing that Animator, not create a new Node - * if one already exists. - */ - private HashMap mNodeMap = new HashMap(); - - /** - * Set of all nodes created for this AnimatorSet. This list is used upon - * starting the set, and the nodes are placed in sorted order into the - * sortedNodes collection. - */ - private ArrayList mNodes = new ArrayList(); - - /** - * The sorted list of nodes. This is the order in which the animations will - * be played. The details about when exactly they will be played depend - * on the dependency relationships of the nodes. - */ - private ArrayList mSortedNodes = new ArrayList(); - - /** - * Flag indicating whether the nodes should be sorted prior to playing. This - * flag allows us to cache the previous sorted nodes so that if the sequence - * is replayed with no changes, it does not have to re-sort the nodes again. - */ - private boolean mNeedsSort = true; - - private AnimatorSetListener mSetListener = null; - - /** - * Flag indicating that the AnimatorSet has been manually - * terminated (by calling cancel() or end()). - * This flag is used to avoid starting other animations when currently-playing - * child animations of this AnimatorSet end. It also determines whether cancel/end - * notifications are sent out via the normal AnimatorSetListener mechanism. - */ - boolean mTerminated = false; - - /** - * Indicates whether an AnimatorSet has been start()'d, whether or - * not there is a nonzero startDelay. - */ - private boolean mStarted = false; - - // The amount of time in ms to delay starting the animation after start() is called - private long mStartDelay = 0; - - // Animator used for a nonzero startDelay - private ValueAnimator mDelayAnim = null; - - - // How long the child animations should last in ms. The default value is negative, which - // simply means that there is no duration set on the AnimatorSet. When a real duration is - // set, it is passed along to the child animations. - private long mDuration = -1; - - - /** - * Sets up this AnimatorSet to play all of the supplied animations at the same time. - * - * @param items The animations that will be started simultaneously. - */ - public void playTogether(Animator... items) { - if (items != null) { - mNeedsSort = true; - Builder builder = play(items[0]); - for (int i = 1; i < items.length; ++i) { - builder.with(items[i]); - } - } - } - - /** - * Sets up this AnimatorSet to play all of the supplied animations at the same time. - * - * @param items The animations that will be started simultaneously. - */ - public void playTogether(Collection items) { - if (items != null && items.size() > 0) { - mNeedsSort = true; - Builder builder = null; - for (Animator anim : items) { - if (builder == null) { - builder = play(anim); - } else { - builder.with(anim); - } - } - } - } - - /** - * Sets up this AnimatorSet to play each of the supplied animations when the - * previous animation ends. - * - * @param items The animations that will be started one after another. - */ - public void playSequentially(Animator... items) { - if (items != null) { - mNeedsSort = true; - if (items.length == 1) { - play(items[0]); - } else { - for (int i = 0; i < items.length - 1; ++i) { - play(items[i]).before(items[i+1]); - } - } - } - } - - /** - * Sets up this AnimatorSet to play each of the supplied animations when the - * previous animation ends. - * - * @param items The animations that will be started one after another. - */ - public void playSequentially(List items) { - if (items != null && items.size() > 0) { - mNeedsSort = true; - if (items.size() == 1) { - play(items.get(0)); - } else { - for (int i = 0; i < items.size() - 1; ++i) { - play(items.get(i)).before(items.get(i+1)); - } - } - } - } - - /** - * Returns the current list of child Animator objects controlled by this - * AnimatorSet. This is a copy of the internal list; modifications to the returned list - * will not affect the AnimatorSet, although changes to the underlying Animator objects - * will affect those objects being managed by the AnimatorSet. - * - * @return ArrayList The list of child animations of this AnimatorSet. - */ - public ArrayList getChildAnimations() { - ArrayList childList = new ArrayList(); - for (Node node : mNodes) { - childList.add(node.animation); - } - return childList; - } - - /** - * Sets the target object for all current {@link #getChildAnimations() child animations} - * of this AnimatorSet that take targets ({@link ObjectAnimator} and - * AnimatorSet). - * - * @param target The object being animated - */ - @Override - public void setTarget(Object target) { - for (Node node : mNodes) { - Animator animation = node.animation; - if (animation instanceof AnimatorSet) { - ((AnimatorSet)animation).setTarget(target); - } else if (animation instanceof ObjectAnimator) { - ((ObjectAnimator)animation).setTarget(target); - } - } - } - - /** - * Sets the TimeInterpolator for all current {@link #getChildAnimations() child animations} - * of this AnimatorSet. - * - * @param interpolator the interpolator to be used by each child animation of this AnimatorSet - */ - @Override - public void setInterpolator(/*Time*/Interpolator interpolator) { - for (Node node : mNodes) { - node.animation.setInterpolator(interpolator); - } - } - - /** - * This method creates a Builder object, which is used to - * set up playing constraints. This initial play() method - * tells the Builder the animation that is the dependency for - * the succeeding commands to the Builder. For example, - * calling play(a1).with(a2) sets up the AnimatorSet to play - * a1 and a2 at the same time, - * play(a1).before(a2) sets up the AnimatorSet to play - * a1 first, followed by a2, and - * play(a1).after(a2) sets up the AnimatorSet to play - * a2 first, followed by a1. - * - *

Note that play() is the only way to tell the - * Builder the animation upon which the dependency is created, - * so successive calls to the various functions in Builder - * will all refer to the initial parameter supplied in play() - * as the dependency of the other animations. For example, calling - * play(a1).before(a2).before(a3) will play both a2 - * and a3 when a1 ends; it does not set up a dependency between - * a2 and a3.

- * - * @param anim The animation that is the dependency used in later calls to the - * methods in the returned Builder object. A null parameter will result - * in a null Builder return value. - * @return Builder The object that constructs the AnimatorSet based on the dependencies - * outlined in the calls to play and the other methods in the - * BuilderNote that canceling a AnimatorSet also cancels all of the animations that it - * is responsible for.

- */ - @Override - public void cancel() { - mTerminated = true; - if (isStarted()) { - ArrayList tmpListeners = null; - if (mListeners != null) { - tmpListeners = (ArrayList) mListeners.clone(); - for (AnimatorListener listener : tmpListeners) { - listener.onAnimationCancel(this); - } - } - if (mDelayAnim != null && mDelayAnim.isRunning()) { - // If we're currently in the startDelay period, just cancel that animator and - // send out the end event to all listeners - mDelayAnim.cancel(); - } else if (mSortedNodes.size() > 0) { - for (Node node : mSortedNodes) { - node.animation.cancel(); - } - } - if (tmpListeners != null) { - for (AnimatorListener listener : tmpListeners) { - listener.onAnimationEnd(this); - } - } - mStarted = false; - } - } - - /** - * {@inheritDoc} - * - *

Note that ending a AnimatorSet also ends all of the animations that it is - * responsible for.

- */ - @Override - public void end() { - mTerminated = true; - if (isStarted()) { - if (mSortedNodes.size() != mNodes.size()) { - // hasn't been started yet - sort the nodes now, then end them - sortNodes(); - for (Node node : mSortedNodes) { - if (mSetListener == null) { - mSetListener = new AnimatorSetListener(this); - } - node.animation.addListener(mSetListener); - } - } - if (mDelayAnim != null) { - mDelayAnim.cancel(); - } - if (mSortedNodes.size() > 0) { - for (Node node : mSortedNodes) { - node.animation.end(); - } - } - if (mListeners != null) { - ArrayList tmpListeners = - (ArrayList) mListeners.clone(); - for (AnimatorListener listener : tmpListeners) { - listener.onAnimationEnd(this); - } - } - mStarted = false; - } - } - - /** - * Returns true if any of the child animations of this AnimatorSet have been started and have - * not yet ended. - * @return Whether this AnimatorSet has been started and has not yet ended. - */ - @Override - public boolean isRunning() { - for (Node node : mNodes) { - if (node.animation.isRunning()) { - return true; - } - } - return false; - } - - @Override - public boolean isStarted() { - return mStarted; - } - - /** - * The amount of time, in milliseconds, to delay starting the animation after - * {@link #start()} is called. - * - * @return the number of milliseconds to delay running the animation - */ - @Override - public long getStartDelay() { - return mStartDelay; - } - - /** - * The amount of time, in milliseconds, to delay starting the animation after - * {@link #start()} is called. - - * @param startDelay The amount of the delay, in milliseconds - */ - @Override - public void setStartDelay(long startDelay) { - mStartDelay = startDelay; - } - - /** - * Gets the length of each of the child animations of this AnimatorSet. This value may - * be less than 0, which indicates that no duration has been set on this AnimatorSet - * and each of the child animations will use their own duration. - * - * @return The length of the animation, in milliseconds, of each of the child - * animations of this AnimatorSet. - */ - @Override - public long getDuration() { - return mDuration; - } - - /** - * Sets the length of each of the current child animations of this AnimatorSet. By default, - * each child animation will use its own duration. If the duration is set on the AnimatorSet, - * then each child animation inherits this duration. - * - * @param duration The length of the animation, in milliseconds, of each of the child - * animations of this AnimatorSet. - */ - @Override - public AnimatorSet setDuration(long duration) { - if (duration < 0) { - throw new IllegalArgumentException("duration must be a value of zero or greater"); - } - for (Node node : mNodes) { - // TODO: don't set the duration of the timing-only nodes created by AnimatorSet to - // insert "play-after" delays - node.animation.setDuration(duration); - } - mDuration = duration; - return this; - } - - @Override - public void setupStartValues() { - for (Node node : mNodes) { - node.animation.setupStartValues(); - } - } - - @Override - public void setupEndValues() { - for (Node node : mNodes) { - node.animation.setupEndValues(); - } - } - - /** - * {@inheritDoc} - * - *

Starting this AnimatorSet will, in turn, start the animations for which - * it is responsible. The details of when exactly those animations are started depends on - * the dependency relationships that have been set up between the animations. - */ - @Override - public void start() { - mTerminated = false; - mStarted = true; - - // First, sort the nodes (if necessary). This will ensure that sortedNodes - // contains the animation nodes in the correct order. - sortNodes(); - - int numSortedNodes = mSortedNodes.size(); - for (int i = 0; i < numSortedNodes; ++i) { - Node node = mSortedNodes.get(i); - // First, clear out the old listeners - ArrayList oldListeners = node.animation.getListeners(); - if (oldListeners != null && oldListeners.size() > 0) { - final ArrayList clonedListeners = new - ArrayList(oldListeners); - - for (AnimatorListener listener : clonedListeners) { - if (listener instanceof DependencyListener || - listener instanceof AnimatorSetListener) { - node.animation.removeListener(listener); - } - } - } - } - - // nodesToStart holds the list of nodes to be started immediately. We don't want to - // start the animations in the loop directly because we first need to set up - // dependencies on all of the nodes. For example, we don't want to start an animation - // when some other animation also wants to start when the first animation begins. - final ArrayList nodesToStart = new ArrayList(); - for (int i = 0; i < numSortedNodes; ++i) { - Node node = mSortedNodes.get(i); - if (mSetListener == null) { - mSetListener = new AnimatorSetListener(this); - } - if (node.dependencies == null || node.dependencies.size() == 0) { - nodesToStart.add(node); - } else { - int numDependencies = node.dependencies.size(); - for (int j = 0; j < numDependencies; ++j) { - Dependency dependency = node.dependencies.get(j); - dependency.node.animation.addListener( - new DependencyListener(this, node, dependency.rule)); - } - node.tmpDependencies = (ArrayList) node.dependencies.clone(); - } - node.animation.addListener(mSetListener); - } - // Now that all dependencies are set up, start the animations that should be started. - if (mStartDelay <= 0) { - for (Node node : nodesToStart) { - node.animation.start(); - mPlayingSet.add(node.animation); - } - } else { - mDelayAnim = ValueAnimator.ofFloat(0f, 1f); - mDelayAnim.setDuration(mStartDelay); - mDelayAnim.addListener(new AnimatorListenerAdapter() { - boolean canceled = false; - public void onAnimationCancel(Animator anim) { - canceled = true; - } - public void onAnimationEnd(Animator anim) { - if (!canceled) { - int numNodes = nodesToStart.size(); - for (int i = 0; i < numNodes; ++i) { - Node node = nodesToStart.get(i); - node.animation.start(); - mPlayingSet.add(node.animation); - } - } - } - }); - mDelayAnim.start(); - } - if (mListeners != null) { - ArrayList tmpListeners = - (ArrayList) mListeners.clone(); - int numListeners = tmpListeners.size(); - for (int i = 0; i < numListeners; ++i) { - tmpListeners.get(i).onAnimationStart(this); - } - } - if (mNodes.size() == 0 && mStartDelay == 0) { - // Handle unusual case where empty AnimatorSet is started - should send out - // end event immediately since the event will not be sent out at all otherwise - mStarted = false; - if (mListeners != null) { - ArrayList tmpListeners = - (ArrayList) mListeners.clone(); - int numListeners = tmpListeners.size(); - for (int i = 0; i < numListeners; ++i) { - tmpListeners.get(i).onAnimationEnd(this); - } - } - } - } - - @Override - public AnimatorSet clone() { - final AnimatorSet anim = (AnimatorSet) super.clone(); - /* - * The basic clone() operation copies all items. This doesn't work very well for - * AnimatorSet, because it will copy references that need to be recreated and state - * that may not apply. What we need to do now is put the clone in an uninitialized - * state, with fresh, empty data structures. Then we will build up the nodes list - * manually, as we clone each Node (and its animation). The clone will then be sorted, - * and will populate any appropriate lists, when it is started. - */ - anim.mNeedsSort = true; - anim.mTerminated = false; - anim.mStarted = false; - anim.mPlayingSet = new ArrayList(); - anim.mNodeMap = new HashMap(); - anim.mNodes = new ArrayList(); - anim.mSortedNodes = new ArrayList(); - - // Walk through the old nodes list, cloning each node and adding it to the new nodemap. - // One problem is that the old node dependencies point to nodes in the old AnimatorSet. - // We need to track the old/new nodes in order to reconstruct the dependencies in the clone. - HashMap nodeCloneMap = new HashMap(); // - for (Node node : mNodes) { - Node nodeClone = node.clone(); - nodeCloneMap.put(node, nodeClone); - anim.mNodes.add(nodeClone); - anim.mNodeMap.put(nodeClone.animation, nodeClone); - // Clear out the dependencies in the clone; we'll set these up manually later - nodeClone.dependencies = null; - nodeClone.tmpDependencies = null; - nodeClone.nodeDependents = null; - nodeClone.nodeDependencies = null; - // clear out any listeners that were set up by the AnimatorSet; these will - // be set up when the clone's nodes are sorted - ArrayList cloneListeners = nodeClone.animation.getListeners(); - if (cloneListeners != null) { - ArrayList listenersToRemove = null; - for (AnimatorListener listener : cloneListeners) { - if (listener instanceof AnimatorSetListener) { - if (listenersToRemove == null) { - listenersToRemove = new ArrayList(); - } - listenersToRemove.add(listener); - } - } - if (listenersToRemove != null) { - for (AnimatorListener listener : listenersToRemove) { - cloneListeners.remove(listener); - } - } - } - } - // Now that we've cloned all of the nodes, we're ready to walk through their - // dependencies, mapping the old dependencies to the new nodes - for (Node node : mNodes) { - Node nodeClone = nodeCloneMap.get(node); - if (node.dependencies != null) { - for (Dependency dependency : node.dependencies) { - Node clonedDependencyNode = nodeCloneMap.get(dependency.node); - Dependency cloneDependency = new Dependency(clonedDependencyNode, - dependency.rule); - nodeClone.addDependency(cloneDependency); - } - } - } - - return anim; - } - - /** - * This class is the mechanism by which animations are started based on events in other - * animations. If an animation has multiple dependencies on other animations, then - * all dependencies must be satisfied before the animation is started. - */ - private static class DependencyListener implements AnimatorListener { - - private AnimatorSet mAnimatorSet; - - // The node upon which the dependency is based. - private Node mNode; - - // The Dependency rule (WITH or AFTER) that the listener should wait for on - // the node - private int mRule; - - public DependencyListener(AnimatorSet animatorSet, Node node, int rule) { - this.mAnimatorSet = animatorSet; - this.mNode = node; - this.mRule = rule; - } - - /** - * Ignore cancel events for now. We may want to handle this eventually, - * to prevent follow-on animations from running when some dependency - * animation is canceled. - */ - public void onAnimationCancel(Animator animation) { - } - - /** - * An end event is received - see if this is an event we are listening for - */ - public void onAnimationEnd(Animator animation) { - if (mRule == Dependency.AFTER) { - startIfReady(animation); - } - } - - /** - * Ignore repeat events for now - */ - public void onAnimationRepeat(Animator animation) { - } - - /** - * A start event is received - see if this is an event we are listening for - */ - public void onAnimationStart(Animator animation) { - if (mRule == Dependency.WITH) { - startIfReady(animation); - } - } - - /** - * Check whether the event received is one that the node was waiting for. - * If so, mark it as complete and see whether it's time to start - * the animation. - * @param dependencyAnimation the animation that sent the event. - */ - private void startIfReady(Animator dependencyAnimation) { - if (mAnimatorSet.mTerminated) { - // if the parent AnimatorSet was canceled, then don't start any dependent anims - return; - } - Dependency dependencyToRemove = null; - int numDependencies = mNode.tmpDependencies.size(); - for (int i = 0; i < numDependencies; ++i) { - Dependency dependency = mNode.tmpDependencies.get(i); - if (dependency.rule == mRule && - dependency.node.animation == dependencyAnimation) { - // rule fired - remove the dependency and listener and check to - // see whether it's time to start the animation - dependencyToRemove = dependency; - dependencyAnimation.removeListener(this); - break; - } - } - mNode.tmpDependencies.remove(dependencyToRemove); - if (mNode.tmpDependencies.size() == 0) { - // all dependencies satisfied: start the animation - mNode.animation.start(); - mAnimatorSet.mPlayingSet.add(mNode.animation); - } - } - - } - - private class AnimatorSetListener implements AnimatorListener { - - private AnimatorSet mAnimatorSet; - - AnimatorSetListener(AnimatorSet animatorSet) { - mAnimatorSet = animatorSet; - } - - public void onAnimationCancel(Animator animation) { - if (!mTerminated) { - // Listeners are already notified of the AnimatorSet canceling in cancel(). - // The logic below only kicks in when animations end normally - if (mPlayingSet.size() == 0) { - if (mListeners != null) { - int numListeners = mListeners.size(); - for (int i = 0; i < numListeners; ++i) { - mListeners.get(i).onAnimationCancel(mAnimatorSet); - } - } - } - } - } - - public void onAnimationEnd(Animator animation) { - animation.removeListener(this); - mPlayingSet.remove(animation); - Node animNode = mAnimatorSet.mNodeMap.get(animation); - animNode.done = true; - if (!mTerminated) { - // Listeners are already notified of the AnimatorSet ending in cancel() or - // end(); the logic below only kicks in when animations end normally - ArrayList sortedNodes = mAnimatorSet.mSortedNodes; - boolean allDone = true; - int numSortedNodes = sortedNodes.size(); - for (int i = 0; i < numSortedNodes; ++i) { - if (!sortedNodes.get(i).done) { - allDone = false; - break; - } - } - if (allDone) { - // If this was the last child animation to end, then notify listeners that this - // AnimatorSet has ended - if (mListeners != null) { - ArrayList tmpListeners = - (ArrayList) mListeners.clone(); - int numListeners = tmpListeners.size(); - for (int i = 0; i < numListeners; ++i) { - tmpListeners.get(i).onAnimationEnd(mAnimatorSet); - } - } - mAnimatorSet.mStarted = false; - } - } - } - - // Nothing to do - public void onAnimationRepeat(Animator animation) { - } - - // Nothing to do - public void onAnimationStart(Animator animation) { - } - - } - - /** - * This method sorts the current set of nodes, if needed. The sort is a simple - * DependencyGraph sort, which goes like this: - * - All nodes without dependencies become 'roots' - * - while roots list is not null - * - for each root r - * - add r to sorted list - * - remove r as a dependency from any other node - * - any nodes with no dependencies are added to the roots list - */ - private void sortNodes() { - if (mNeedsSort) { - mSortedNodes.clear(); - ArrayList roots = new ArrayList(); - int numNodes = mNodes.size(); - for (int i = 0; i < numNodes; ++i) { - Node node = mNodes.get(i); - if (node.dependencies == null || node.dependencies.size() == 0) { - roots.add(node); - } - } - ArrayList tmpRoots = new ArrayList(); - while (roots.size() > 0) { - int numRoots = roots.size(); - for (int i = 0; i < numRoots; ++i) { - Node root = roots.get(i); - mSortedNodes.add(root); - if (root.nodeDependents != null) { - int numDependents = root.nodeDependents.size(); - for (int j = 0; j < numDependents; ++j) { - Node node = root.nodeDependents.get(j); - node.nodeDependencies.remove(root); - if (node.nodeDependencies.size() == 0) { - tmpRoots.add(node); - } - } - } - } - roots.clear(); - roots.addAll(tmpRoots); - tmpRoots.clear(); - } - mNeedsSort = false; - if (mSortedNodes.size() != mNodes.size()) { - throw new IllegalStateException("Circular dependencies cannot exist" - + " in AnimatorSet"); - } - } else { - // Doesn't need sorting, but still need to add in the nodeDependencies list - // because these get removed as the event listeners fire and the dependencies - // are satisfied - int numNodes = mNodes.size(); - for (int i = 0; i < numNodes; ++i) { - Node node = mNodes.get(i); - if (node.dependencies != null && node.dependencies.size() > 0) { - int numDependencies = node.dependencies.size(); - for (int j = 0; j < numDependencies; ++j) { - Dependency dependency = node.dependencies.get(j); - if (node.nodeDependencies == null) { - node.nodeDependencies = new ArrayList(); - } - if (!node.nodeDependencies.contains(dependency.node)) { - node.nodeDependencies.add(dependency.node); - } - } - } - // nodes are 'done' by default; they become un-done when started, and done - // again when ended - node.done = false; - } - } - } - - /** - * Dependency holds information about the node that some other node is - * dependent upon and the nature of that dependency. - * - */ - private static class Dependency { - static final int WITH = 0; // dependent node must start with this dependency node - static final int AFTER = 1; // dependent node must start when this dependency node finishes - - // The node that the other node with this Dependency is dependent upon - public Node node; - - // The nature of the dependency (WITH or AFTER) - public int rule; - - public Dependency(Node node, int rule) { - this.node = node; - this.rule = rule; - } - } - - /** - * A Node is an embodiment of both the Animator that it wraps as well as - * any dependencies that are associated with that Animation. This includes - * both dependencies upon other nodes (in the dependencies list) as - * well as dependencies of other nodes upon this (in the nodeDependents list). - */ - private static class Node implements Cloneable { - public Animator animation; - - /** - * These are the dependencies that this node's animation has on other - * nodes. For example, if this node's animation should begin with some - * other animation ends, then there will be an item in this node's - * dependencies list for that other animation's node. - */ - public ArrayList dependencies = null; - - /** - * tmpDependencies is a runtime detail. We use the dependencies list for sorting. - * But we also use the list to keep track of when multiple dependencies are satisfied, - * but removing each dependency as it is satisfied. We do not want to remove - * the dependency itself from the list, because we need to retain that information - * if the AnimatorSet is launched in the future. So we create a copy of the dependency - * list when the AnimatorSet starts and use this tmpDependencies list to track the - * list of satisfied dependencies. - */ - public ArrayList tmpDependencies = null; - - /** - * nodeDependencies is just a list of the nodes that this Node is dependent upon. - * This information is used in sortNodes(), to determine when a node is a root. - */ - public ArrayList nodeDependencies = null; - - /** - * nodeDepdendents is the list of nodes that have this node as a dependency. This - * is a utility field used in sortNodes to facilitate removing this node as a - * dependency when it is a root node. - */ - public ArrayList nodeDependents = null; - - /** - * Flag indicating whether the animation in this node is finished. This flag - * is used by AnimatorSet to check, as each animation ends, whether all child animations - * are done and it's time to send out an end event for the entire AnimatorSet. - */ - public boolean done = false; - - /** - * Constructs the Node with the animation that it encapsulates. A Node has no - * dependencies by default; dependencies are added via the addDependency() - * method. - * - * @param animation The animation that the Node encapsulates. - */ - public Node(Animator animation) { - this.animation = animation; - } - - /** - * Add a dependency to this Node. The dependency includes information about the - * node that this node is dependency upon and the nature of the dependency. - * @param dependency - */ - public void addDependency(Dependency dependency) { - if (dependencies == null) { - dependencies = new ArrayList(); - nodeDependencies = new ArrayList(); - } - dependencies.add(dependency); - if (!nodeDependencies.contains(dependency.node)) { - nodeDependencies.add(dependency.node); - } - Node dependencyNode = dependency.node; - if (dependencyNode.nodeDependents == null) { - dependencyNode.nodeDependents = new ArrayList(); - } - dependencyNode.nodeDependents.add(this); - } - - @Override - public Node clone() { - try { - Node node = (Node) super.clone(); - node.animation = animation.clone(); - return node; - } catch (CloneNotSupportedException e) { - throw new AssertionError(); - } - } - } - - /** - * The Builder object is a utility class to facilitate adding animations to a - * AnimatorSet along with the relationships between the various animations. The - * intention of the Builder methods, along with the {@link - * AnimatorSet#play(Animator) play()} method of AnimatorSet is to make it possible - * to express the dependency relationships of animations in a natural way. Developers can also - * use the {@link AnimatorSet#playTogether(Animator[]) playTogether()} and {@link - * AnimatorSet#playSequentially(Animator[]) playSequentially()} methods if these suit the need, - * but it might be easier in some situations to express the AnimatorSet of animations in pairs. - *

- *

The Builder object cannot be constructed directly, but is rather constructed - * internally via a call to {@link AnimatorSet#play(Animator)}.

- *

- *

For example, this sets up a AnimatorSet to play anim1 and anim2 at the same time, anim3 to - * play when anim2 finishes, and anim4 to play when anim3 finishes:

- *
-     *     AnimatorSet s = new AnimatorSet();
-     *     s.play(anim1).with(anim2);
-     *     s.play(anim2).before(anim3);
-     *     s.play(anim4).after(anim3);
-     * 
- *

- *

Note in the example that both {@link Builder#before(Animator)} and {@link - * Builder#after(Animator)} are used. These are just different ways of expressing the same - * relationship and are provided to make it easier to say things in a way that is more natural, - * depending on the situation.

- *

- *

It is possible to make several calls into the same Builder object to express - * multiple relationships. However, note that it is only the animation passed into the initial - * {@link AnimatorSet#play(Animator)} method that is the dependency in any of the successive - * calls to the Builder object. For example, the following code starts both anim2 - * and anim3 when anim1 ends; there is no direct dependency relationship between anim2 and - * anim3: - *

-     *   AnimatorSet s = new AnimatorSet();
-     *   s.play(anim1).before(anim2).before(anim3);
-     * 
- * If the desired result is to play anim1 then anim2 then anim3, this code expresses the - * relationship correctly:

- *
-     *   AnimatorSet s = new AnimatorSet();
-     *   s.play(anim1).before(anim2);
-     *   s.play(anim2).before(anim3);
-     * 
- *

- *

Note that it is possible to express relationships that cannot be resolved and will not - * result in sensible results. For example, play(anim1).after(anim1) makes no - * sense. In general, circular dependencies like this one (or more indirect ones where a depends - * on b, which depends on c, which depends on a) should be avoided. Only create AnimatorSets - * that can boil down to a simple, one-way relationship of animations starting with, before, and - * after other, different, animations.

- */ - public class Builder { - - /** - * This tracks the current node being processed. It is supplied to the play() method - * of AnimatorSet and passed into the constructor of Builder. - */ - private Node mCurrentNode; - - /** - * package-private constructor. Builders are only constructed by AnimatorSet, when the - * play() method is called. - * - * @param anim The animation that is the dependency for the other animations passed into - * the other methods of this Builder object. - */ - Builder(Animator anim) { - mCurrentNode = mNodeMap.get(anim); - if (mCurrentNode == null) { - mCurrentNode = new Node(anim); - mNodeMap.put(anim, mCurrentNode); - mNodes.add(mCurrentNode); - } - } - - /** - * Sets up the given animation to play at the same time as the animation supplied in the - * {@link AnimatorSet#play(Animator)} call that created this Builder object. - * - * @param anim The animation that will play when the animation supplied to the - * {@link AnimatorSet#play(Animator)} method starts. - */ - public Builder with(Animator anim) { - Node node = mNodeMap.get(anim); - if (node == null) { - node = new Node(anim); - mNodeMap.put(anim, node); - mNodes.add(node); - } - Dependency dependency = new Dependency(mCurrentNode, Dependency.WITH); - node.addDependency(dependency); - return this; - } - - /** - * Sets up the given animation to play when the animation supplied in the - * {@link AnimatorSet#play(Animator)} call that created this Builder object - * ends. - * - * @param anim The animation that will play when the animation supplied to the - * {@link AnimatorSet#play(Animator)} method ends. - */ - public Builder before(Animator anim) { - Node node = mNodeMap.get(anim); - if (node == null) { - node = new Node(anim); - mNodeMap.put(anim, node); - mNodes.add(node); - } - Dependency dependency = new Dependency(mCurrentNode, Dependency.AFTER); - node.addDependency(dependency); - return this; - } - - /** - * Sets up the given animation to play when the animation supplied in the - * {@link AnimatorSet#play(Animator)} call that created this Builder object - * to start when the animation supplied in this method call ends. - * - * @param anim The animation whose end will cause the animation supplied to the - * {@link AnimatorSet#play(Animator)} method to play. - */ - public Builder after(Animator anim) { - Node node = mNodeMap.get(anim); - if (node == null) { - node = new Node(anim); - mNodeMap.put(anim, node); - mNodes.add(node); - } - Dependency dependency = new Dependency(node, Dependency.AFTER); - mCurrentNode.addDependency(dependency); - return this; - } - - /** - * Sets up the animation supplied in the - * {@link AnimatorSet#play(Animator)} call that created this Builder object - * to play when the given amount of time elapses. - * - * @param delay The number of milliseconds that should elapse before the - * animation starts. - */ - public Builder after(long delay) { - // setup dummy ValueAnimator just to run the clock - ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f); - anim.setDuration(delay); - after(anim); - return this; - } - - } - -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/FloatEvaluator.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/FloatEvaluator.java deleted file mode 100644 index e41019364..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/FloatEvaluator.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.nineoldandroids.animation; - -/** - * This evaluator can be used to perform type interpolation between float values. - */ -public class FloatEvaluator implements TypeEvaluator { - - /** - * This function returns the result of linearly interpolating the start and end values, with - * fraction representing the proportion between the start and end values. The - * calculation is a simple parametric calculation: result = x0 + t * (v1 - v0), - * where x0 is startValue, x1 is endValue, - * and t is fraction. - * - * @param fraction The fraction from the starting to the ending values - * @param startValue The start value; should be of type float or - * Float - * @param endValue The end value; should be of type float or Float - * @return A linear interpolation between the start and end values, given the - * fraction parameter. - */ - public Float evaluate(float fraction, Number startValue, Number endValue) { - float startFloat = startValue.floatValue(); - return startFloat + fraction * (endValue.floatValue() - startFloat); - } -} \ No newline at end of file diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/FloatKeyframeSet.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/FloatKeyframeSet.java deleted file mode 100644 index 6d9dafa7a..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/FloatKeyframeSet.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.nineoldandroids.animation; - -import java.util.ArrayList; -import android.view.animation.Interpolator; - -import com.actionbarsherlock.internal.nineoldandroids.animation.Keyframe.FloatKeyframe; - -/** - * This class holds a collection of FloatKeyframe objects and is called by ValueAnimator to calculate - * values between those keyframes for a given animation. The class internal to the animation - * package because it is an implementation detail of how Keyframes are stored and used. - * - *

This type-specific subclass of KeyframeSet, along with the other type-specific subclass for - * int, exists to speed up the getValue() method when there is no custom - * TypeEvaluator set for the animation, so that values can be calculated without autoboxing to the - * Object equivalents of these primitive types.

- */ -@SuppressWarnings("unchecked") -class FloatKeyframeSet extends KeyframeSet { - private float firstValue; - private float lastValue; - private float deltaValue; - private boolean firstTime = true; - - public FloatKeyframeSet(FloatKeyframe... keyframes) { - super(keyframes); - } - - @Override - public Object getValue(float fraction) { - return getFloatValue(fraction); - } - - @Override - public FloatKeyframeSet clone() { - ArrayList keyframes = mKeyframes; - int numKeyframes = mKeyframes.size(); - FloatKeyframe[] newKeyframes = new FloatKeyframe[numKeyframes]; - for (int i = 0; i < numKeyframes; ++i) { - newKeyframes[i] = (FloatKeyframe) keyframes.get(i).clone(); - } - FloatKeyframeSet newSet = new FloatKeyframeSet(newKeyframes); - return newSet; - } - - public float getFloatValue(float fraction) { - if (mNumKeyframes == 2) { - if (firstTime) { - firstTime = false; - firstValue = ((FloatKeyframe) mKeyframes.get(0)).getFloatValue(); - lastValue = ((FloatKeyframe) mKeyframes.get(1)).getFloatValue(); - deltaValue = lastValue - firstValue; - } - if (mInterpolator != null) { - fraction = mInterpolator.getInterpolation(fraction); - } - if (mEvaluator == null) { - return firstValue + fraction * deltaValue; - } else { - return ((Number)mEvaluator.evaluate(fraction, firstValue, lastValue)).floatValue(); - } - } - if (fraction <= 0f) { - final FloatKeyframe prevKeyframe = (FloatKeyframe) mKeyframes.get(0); - final FloatKeyframe nextKeyframe = (FloatKeyframe) mKeyframes.get(1); - float prevValue = prevKeyframe.getFloatValue(); - float nextValue = nextKeyframe.getFloatValue(); - float prevFraction = prevKeyframe.getFraction(); - float nextFraction = nextKeyframe.getFraction(); - final /*Time*/Interpolator interpolator = nextKeyframe.getInterpolator(); - if (interpolator != null) { - fraction = interpolator.getInterpolation(fraction); - } - float intervalFraction = (fraction - prevFraction) / (nextFraction - prevFraction); - return mEvaluator == null ? - prevValue + intervalFraction * (nextValue - prevValue) : - ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)). - floatValue(); - } else if (fraction >= 1f) { - final FloatKeyframe prevKeyframe = (FloatKeyframe) mKeyframes.get(mNumKeyframes - 2); - final FloatKeyframe nextKeyframe = (FloatKeyframe) mKeyframes.get(mNumKeyframes - 1); - float prevValue = prevKeyframe.getFloatValue(); - float nextValue = nextKeyframe.getFloatValue(); - float prevFraction = prevKeyframe.getFraction(); - float nextFraction = nextKeyframe.getFraction(); - final /*Time*/Interpolator interpolator = nextKeyframe.getInterpolator(); - if (interpolator != null) { - fraction = interpolator.getInterpolation(fraction); - } - float intervalFraction = (fraction - prevFraction) / (nextFraction - prevFraction); - return mEvaluator == null ? - prevValue + intervalFraction * (nextValue - prevValue) : - ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)). - floatValue(); - } - FloatKeyframe prevKeyframe = (FloatKeyframe) mKeyframes.get(0); - for (int i = 1; i < mNumKeyframes; ++i) { - FloatKeyframe nextKeyframe = (FloatKeyframe) mKeyframes.get(i); - if (fraction < nextKeyframe.getFraction()) { - final /*Time*/Interpolator interpolator = nextKeyframe.getInterpolator(); - if (interpolator != null) { - fraction = interpolator.getInterpolation(fraction); - } - float intervalFraction = (fraction - prevKeyframe.getFraction()) / - (nextKeyframe.getFraction() - prevKeyframe.getFraction()); - float prevValue = prevKeyframe.getFloatValue(); - float nextValue = nextKeyframe.getFloatValue(); - return mEvaluator == null ? - prevValue + intervalFraction * (nextValue - prevValue) : - ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)). - floatValue(); - } - prevKeyframe = nextKeyframe; - } - // shouldn't get here - return ((Number)mKeyframes.get(mNumKeyframes - 1).getValue()).floatValue(); - } - -} - diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/IntEvaluator.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/IntEvaluator.java deleted file mode 100644 index ed5e79ec6..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/IntEvaluator.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.nineoldandroids.animation; - -/** - * This evaluator can be used to perform type interpolation between int values. - */ -public class IntEvaluator implements TypeEvaluator { - - /** - * This function returns the result of linearly interpolating the start and end values, with - * fraction representing the proportion between the start and end values. The - * calculation is a simple parametric calculation: result = x0 + t * (v1 - v0), - * where x0 is startValue, x1 is endValue, - * and t is fraction. - * - * @param fraction The fraction from the starting to the ending values - * @param startValue The start value; should be of type int or - * Integer - * @param endValue The end value; should be of type int or Integer - * @return A linear interpolation between the start and end values, given the - * fraction parameter. - */ - public Integer evaluate(float fraction, Integer startValue, Integer endValue) { - int startInt = startValue; - return (int)(startInt + fraction * (endValue - startInt)); - } -} \ No newline at end of file diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/IntKeyframeSet.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/IntKeyframeSet.java deleted file mode 100644 index e9215e7f8..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/IntKeyframeSet.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.nineoldandroids.animation; - -import java.util.ArrayList; -import android.view.animation.Interpolator; - -import com.actionbarsherlock.internal.nineoldandroids.animation.Keyframe.IntKeyframe; - -/** - * This class holds a collection of IntKeyframe objects and is called by ValueAnimator to calculate - * values between those keyframes for a given animation. The class internal to the animation - * package because it is an implementation detail of how Keyframes are stored and used. - * - *

This type-specific subclass of KeyframeSet, along with the other type-specific subclass for - * float, exists to speed up the getValue() method when there is no custom - * TypeEvaluator set for the animation, so that values can be calculated without autoboxing to the - * Object equivalents of these primitive types.

- */ -@SuppressWarnings("unchecked") -class IntKeyframeSet extends KeyframeSet { - private int firstValue; - private int lastValue; - private int deltaValue; - private boolean firstTime = true; - - public IntKeyframeSet(IntKeyframe... keyframes) { - super(keyframes); - } - - @Override - public Object getValue(float fraction) { - return getIntValue(fraction); - } - - @Override - public IntKeyframeSet clone() { - ArrayList keyframes = mKeyframes; - int numKeyframes = mKeyframes.size(); - IntKeyframe[] newKeyframes = new IntKeyframe[numKeyframes]; - for (int i = 0; i < numKeyframes; ++i) { - newKeyframes[i] = (IntKeyframe) keyframes.get(i).clone(); - } - IntKeyframeSet newSet = new IntKeyframeSet(newKeyframes); - return newSet; - } - - public int getIntValue(float fraction) { - if (mNumKeyframes == 2) { - if (firstTime) { - firstTime = false; - firstValue = ((IntKeyframe) mKeyframes.get(0)).getIntValue(); - lastValue = ((IntKeyframe) mKeyframes.get(1)).getIntValue(); - deltaValue = lastValue - firstValue; - } - if (mInterpolator != null) { - fraction = mInterpolator.getInterpolation(fraction); - } - if (mEvaluator == null) { - return firstValue + (int)(fraction * deltaValue); - } else { - return ((Number)mEvaluator.evaluate(fraction, firstValue, lastValue)).intValue(); - } - } - if (fraction <= 0f) { - final IntKeyframe prevKeyframe = (IntKeyframe) mKeyframes.get(0); - final IntKeyframe nextKeyframe = (IntKeyframe) mKeyframes.get(1); - int prevValue = prevKeyframe.getIntValue(); - int nextValue = nextKeyframe.getIntValue(); - float prevFraction = prevKeyframe.getFraction(); - float nextFraction = nextKeyframe.getFraction(); - final /*Time*/Interpolator interpolator = nextKeyframe.getInterpolator(); - if (interpolator != null) { - fraction = interpolator.getInterpolation(fraction); - } - float intervalFraction = (fraction - prevFraction) / (nextFraction - prevFraction); - return mEvaluator == null ? - prevValue + (int)(intervalFraction * (nextValue - prevValue)) : - ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)). - intValue(); - } else if (fraction >= 1f) { - final IntKeyframe prevKeyframe = (IntKeyframe) mKeyframes.get(mNumKeyframes - 2); - final IntKeyframe nextKeyframe = (IntKeyframe) mKeyframes.get(mNumKeyframes - 1); - int prevValue = prevKeyframe.getIntValue(); - int nextValue = nextKeyframe.getIntValue(); - float prevFraction = prevKeyframe.getFraction(); - float nextFraction = nextKeyframe.getFraction(); - final /*Time*/Interpolator interpolator = nextKeyframe.getInterpolator(); - if (interpolator != null) { - fraction = interpolator.getInterpolation(fraction); - } - float intervalFraction = (fraction - prevFraction) / (nextFraction - prevFraction); - return mEvaluator == null ? - prevValue + (int)(intervalFraction * (nextValue - prevValue)) : - ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)).intValue(); - } - IntKeyframe prevKeyframe = (IntKeyframe) mKeyframes.get(0); - for (int i = 1; i < mNumKeyframes; ++i) { - IntKeyframe nextKeyframe = (IntKeyframe) mKeyframes.get(i); - if (fraction < nextKeyframe.getFraction()) { - final /*Time*/Interpolator interpolator = nextKeyframe.getInterpolator(); - if (interpolator != null) { - fraction = interpolator.getInterpolation(fraction); - } - float intervalFraction = (fraction - prevKeyframe.getFraction()) / - (nextKeyframe.getFraction() - prevKeyframe.getFraction()); - int prevValue = prevKeyframe.getIntValue(); - int nextValue = nextKeyframe.getIntValue(); - return mEvaluator == null ? - prevValue + (int)(intervalFraction * (nextValue - prevValue)) : - ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)). - intValue(); - } - prevKeyframe = nextKeyframe; - } - // shouldn't get here - return ((Number)mKeyframes.get(mNumKeyframes - 1).getValue()).intValue(); - } - -} - diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/Keyframe.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/Keyframe.java deleted file mode 100644 index ab76fa7f6..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/Keyframe.java +++ /dev/null @@ -1,361 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.nineoldandroids.animation; - -import android.view.animation.Interpolator; - -/** - * This class holds a time/value pair for an animation. The Keyframe class is used - * by {@link ValueAnimator} to define the values that the animation target will have over the course - * of the animation. As the time proceeds from one keyframe to the other, the value of the - * target object will animate between the value at the previous keyframe and the value at the - * next keyframe. Each keyframe also holds an optional {@link TimeInterpolator} - * object, which defines the time interpolation over the intervalue preceding the keyframe. - * - *

The Keyframe class itself is abstract. The type-specific factory methods will return - * a subclass of Keyframe specific to the type of value being stored. This is done to improve - * performance when dealing with the most common cases (e.g., float and - * int values). Other types will fall into a more general Keyframe class that - * treats its values as Objects. Unless your animation requires dealing with a custom type - * or a data structure that needs to be animated directly (and evaluated using an implementation - * of {@link TypeEvaluator}), you should stick to using float and int as animations using those - * types have lower runtime overhead than other types.

- */ -@SuppressWarnings("rawtypes") -public abstract class Keyframe implements Cloneable { - /** - * The time at which mValue will hold true. - */ - float mFraction; - - /** - * The type of the value in this Keyframe. This type is determined at construction time, - * based on the type of the value object passed into the constructor. - */ - Class mValueType; - - /** - * The optional time interpolator for the interval preceding this keyframe. A null interpolator - * (the default) results in linear interpolation over the interval. - */ - private /*Time*/Interpolator mInterpolator = null; - - /** - * Flag to indicate whether this keyframe has a valid value. This flag is used when an - * animation first starts, to populate placeholder keyframes with real values derived - * from the target object. - */ - boolean mHasValue = false; - - /** - * Constructs a Keyframe object with the given time and value. The time defines the - * time, as a proportion of an overall animation's duration, at which the value will hold true - * for the animation. The value for the animation between keyframes will be calculated as - * an interpolation between the values at those keyframes. - * - * @param fraction The time, expressed as a value between 0 and 1, representing the fraction - * of time elapsed of the overall animation duration. - * @param value The value that the object will animate to as the animation time approaches - * the time in this keyframe, and the the value animated from as the time passes the time in - * this keyframe. - */ - public static Keyframe ofInt(float fraction, int value) { - return new IntKeyframe(fraction, value); - } - - /** - * Constructs a Keyframe object with the given time. The value at this time will be derived - * from the target object when the animation first starts (note that this implies that keyframes - * with no initial value must be used as part of an {@link ObjectAnimator}). - * The time defines the - * time, as a proportion of an overall animation's duration, at which the value will hold true - * for the animation. The value for the animation between keyframes will be calculated as - * an interpolation between the values at those keyframes. - * - * @param fraction The time, expressed as a value between 0 and 1, representing the fraction - * of time elapsed of the overall animation duration. - */ - public static Keyframe ofInt(float fraction) { - return new IntKeyframe(fraction); - } - - /** - * Constructs a Keyframe object with the given time and value. The time defines the - * time, as a proportion of an overall animation's duration, at which the value will hold true - * for the animation. The value for the animation between keyframes will be calculated as - * an interpolation between the values at those keyframes. - * - * @param fraction The time, expressed as a value between 0 and 1, representing the fraction - * of time elapsed of the overall animation duration. - * @param value The value that the object will animate to as the animation time approaches - * the time in this keyframe, and the the value animated from as the time passes the time in - * this keyframe. - */ - public static Keyframe ofFloat(float fraction, float value) { - return new FloatKeyframe(fraction, value); - } - - /** - * Constructs a Keyframe object with the given time. The value at this time will be derived - * from the target object when the animation first starts (note that this implies that keyframes - * with no initial value must be used as part of an {@link ObjectAnimator}). - * The time defines the - * time, as a proportion of an overall animation's duration, at which the value will hold true - * for the animation. The value for the animation between keyframes will be calculated as - * an interpolation between the values at those keyframes. - * - * @param fraction The time, expressed as a value between 0 and 1, representing the fraction - * of time elapsed of the overall animation duration. - */ - public static Keyframe ofFloat(float fraction) { - return new FloatKeyframe(fraction); - } - - /** - * Constructs a Keyframe object with the given time and value. The time defines the - * time, as a proportion of an overall animation's duration, at which the value will hold true - * for the animation. The value for the animation between keyframes will be calculated as - * an interpolation between the values at those keyframes. - * - * @param fraction The time, expressed as a value between 0 and 1, representing the fraction - * of time elapsed of the overall animation duration. - * @param value The value that the object will animate to as the animation time approaches - * the time in this keyframe, and the the value animated from as the time passes the time in - * this keyframe. - */ - public static Keyframe ofObject(float fraction, Object value) { - return new ObjectKeyframe(fraction, value); - } - - /** - * Constructs a Keyframe object with the given time. The value at this time will be derived - * from the target object when the animation first starts (note that this implies that keyframes - * with no initial value must be used as part of an {@link ObjectAnimator}). - * The time defines the - * time, as a proportion of an overall animation's duration, at which the value will hold true - * for the animation. The value for the animation between keyframes will be calculated as - * an interpolation between the values at those keyframes. - * - * @param fraction The time, expressed as a value between 0 and 1, representing the fraction - * of time elapsed of the overall animation duration. - */ - public static Keyframe ofObject(float fraction) { - return new ObjectKeyframe(fraction, null); - } - - /** - * Indicates whether this keyframe has a valid value. This method is called internally when - * an {@link ObjectAnimator} first starts; keyframes without values are assigned values at - * that time by deriving the value for the property from the target object. - * - * @return boolean Whether this object has a value assigned. - */ - public boolean hasValue() { - return mHasValue; - } - - /** - * Gets the value for this Keyframe. - * - * @return The value for this Keyframe. - */ - public abstract Object getValue(); - - /** - * Sets the value for this Keyframe. - * - * @param value value for this Keyframe. - */ - public abstract void setValue(Object value); - - /** - * Gets the time for this keyframe, as a fraction of the overall animation duration. - * - * @return The time associated with this keyframe, as a fraction of the overall animation - * duration. This should be a value between 0 and 1. - */ - public float getFraction() { - return mFraction; - } - - /** - * Sets the time for this keyframe, as a fraction of the overall animation duration. - * - * @param fraction time associated with this keyframe, as a fraction of the overall animation - * duration. This should be a value between 0 and 1. - */ - public void setFraction(float fraction) { - mFraction = fraction; - } - - /** - * Gets the optional interpolator for this Keyframe. A value of null indicates - * that there is no interpolation, which is the same as linear interpolation. - * - * @return The optional interpolator for this Keyframe. - */ - public /*Time*/Interpolator getInterpolator() { - return mInterpolator; - } - - /** - * Sets the optional interpolator for this Keyframe. A value of null indicates - * that there is no interpolation, which is the same as linear interpolation. - * - * @return The optional interpolator for this Keyframe. - */ - public void setInterpolator(/*Time*/Interpolator interpolator) { - mInterpolator = interpolator; - } - - /** - * Gets the type of keyframe. This information is used by ValueAnimator to determine the type of - * {@link TypeEvaluator} to use when calculating values between keyframes. The type is based - * on the type of Keyframe created. - * - * @return The type of the value stored in the Keyframe. - */ - public Class getType() { - return mValueType; - } - - @Override - public abstract Keyframe clone(); - - /** - * This internal subclass is used for all types which are not int or float. - */ - static class ObjectKeyframe extends Keyframe { - - /** - * The value of the animation at the time mFraction. - */ - Object mValue; - - ObjectKeyframe(float fraction, Object value) { - mFraction = fraction; - mValue = value; - mHasValue = (value != null); - mValueType = mHasValue ? value.getClass() : Object.class; - } - - public Object getValue() { - return mValue; - } - - public void setValue(Object value) { - mValue = value; - mHasValue = (value != null); - } - - @Override - public ObjectKeyframe clone() { - ObjectKeyframe kfClone = new ObjectKeyframe(getFraction(), mValue); - kfClone.setInterpolator(getInterpolator()); - return kfClone; - } - } - - /** - * Internal subclass used when the keyframe value is of type int. - */ - static class IntKeyframe extends Keyframe { - - /** - * The value of the animation at the time mFraction. - */ - int mValue; - - IntKeyframe(float fraction, int value) { - mFraction = fraction; - mValue = value; - mValueType = int.class; - mHasValue = true; - } - - IntKeyframe(float fraction) { - mFraction = fraction; - mValueType = int.class; - } - - public int getIntValue() { - return mValue; - } - - public Object getValue() { - return mValue; - } - - public void setValue(Object value) { - if (value != null && value.getClass() == Integer.class) { - mValue = ((Integer)value).intValue(); - mHasValue = true; - } - } - - @Override - public IntKeyframe clone() { - IntKeyframe kfClone = new IntKeyframe(getFraction(), mValue); - kfClone.setInterpolator(getInterpolator()); - return kfClone; - } - } - - /** - * Internal subclass used when the keyframe value is of type float. - */ - static class FloatKeyframe extends Keyframe { - /** - * The value of the animation at the time mFraction. - */ - float mValue; - - FloatKeyframe(float fraction, float value) { - mFraction = fraction; - mValue = value; - mValueType = float.class; - mHasValue = true; - } - - FloatKeyframe(float fraction) { - mFraction = fraction; - mValueType = float.class; - } - - public float getFloatValue() { - return mValue; - } - - public Object getValue() { - return mValue; - } - - public void setValue(Object value) { - if (value != null && value.getClass() == Float.class) { - mValue = ((Float)value).floatValue(); - mHasValue = true; - } - } - - @Override - public FloatKeyframe clone() { - FloatKeyframe kfClone = new FloatKeyframe(getFraction(), mValue); - kfClone.setInterpolator(getInterpolator()); - return kfClone; - } - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/KeyframeSet.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/KeyframeSet.java deleted file mode 100644 index a71e1ad3c..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/KeyframeSet.java +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.nineoldandroids.animation; - -import java.util.ArrayList; -import java.util.Arrays; -import android.view.animation.Interpolator; - -import com.actionbarsherlock.internal.nineoldandroids.animation.Keyframe.FloatKeyframe; -import com.actionbarsherlock.internal.nineoldandroids.animation.Keyframe.IntKeyframe; -import com.actionbarsherlock.internal.nineoldandroids.animation.Keyframe.ObjectKeyframe; - -/** - * This class holds a collection of Keyframe objects and is called by ValueAnimator to calculate - * values between those keyframes for a given animation. The class internal to the animation - * package because it is an implementation detail of how Keyframes are stored and used. - */ -@SuppressWarnings({"rawtypes", "unchecked"}) -class KeyframeSet { - - int mNumKeyframes; - - Keyframe mFirstKeyframe; - Keyframe mLastKeyframe; - /*Time*/Interpolator mInterpolator; // only used in the 2-keyframe case - ArrayList mKeyframes; // only used when there are not 2 keyframes - TypeEvaluator mEvaluator; - - - public KeyframeSet(Keyframe... keyframes) { - mNumKeyframes = keyframes.length; - mKeyframes = new ArrayList(); - mKeyframes.addAll(Arrays.asList(keyframes)); - mFirstKeyframe = mKeyframes.get(0); - mLastKeyframe = mKeyframes.get(mNumKeyframes - 1); - mInterpolator = mLastKeyframe.getInterpolator(); - } - - public static KeyframeSet ofInt(int... values) { - int numKeyframes = values.length; - IntKeyframe keyframes[] = new IntKeyframe[Math.max(numKeyframes,2)]; - if (numKeyframes == 1) { - keyframes[0] = (IntKeyframe) Keyframe.ofInt(0f); - keyframes[1] = (IntKeyframe) Keyframe.ofInt(1f, values[0]); - } else { - keyframes[0] = (IntKeyframe) Keyframe.ofInt(0f, values[0]); - for (int i = 1; i < numKeyframes; ++i) { - keyframes[i] = (IntKeyframe) Keyframe.ofInt((float) i / (numKeyframes - 1), values[i]); - } - } - return new IntKeyframeSet(keyframes); - } - - public static KeyframeSet ofFloat(float... values) { - int numKeyframes = values.length; - FloatKeyframe keyframes[] = new FloatKeyframe[Math.max(numKeyframes,2)]; - if (numKeyframes == 1) { - keyframes[0] = (FloatKeyframe) Keyframe.ofFloat(0f); - keyframes[1] = (FloatKeyframe) Keyframe.ofFloat(1f, values[0]); - } else { - keyframes[0] = (FloatKeyframe) Keyframe.ofFloat(0f, values[0]); - for (int i = 1; i < numKeyframes; ++i) { - keyframes[i] = (FloatKeyframe) Keyframe.ofFloat((float) i / (numKeyframes - 1), values[i]); - } - } - return new FloatKeyframeSet(keyframes); - } - - public static KeyframeSet ofKeyframe(Keyframe... keyframes) { - // if all keyframes of same primitive type, create the appropriate KeyframeSet - int numKeyframes = keyframes.length; - boolean hasFloat = false; - boolean hasInt = false; - boolean hasOther = false; - for (int i = 0; i < numKeyframes; ++i) { - if (keyframes[i] instanceof FloatKeyframe) { - hasFloat = true; - } else if (keyframes[i] instanceof IntKeyframe) { - hasInt = true; - } else { - hasOther = true; - } - } - if (hasFloat && !hasInt && !hasOther) { - FloatKeyframe floatKeyframes[] = new FloatKeyframe[numKeyframes]; - for (int i = 0; i < numKeyframes; ++i) { - floatKeyframes[i] = (FloatKeyframe) keyframes[i]; - } - return new FloatKeyframeSet(floatKeyframes); - } else if (hasInt && !hasFloat && !hasOther) { - IntKeyframe intKeyframes[] = new IntKeyframe[numKeyframes]; - for (int i = 0; i < numKeyframes; ++i) { - intKeyframes[i] = (IntKeyframe) keyframes[i]; - } - return new IntKeyframeSet(intKeyframes); - } else { - return new KeyframeSet(keyframes); - } - } - - public static KeyframeSet ofObject(Object... values) { - int numKeyframes = values.length; - ObjectKeyframe keyframes[] = new ObjectKeyframe[Math.max(numKeyframes,2)]; - if (numKeyframes == 1) { - keyframes[0] = (ObjectKeyframe) Keyframe.ofObject(0f); - keyframes[1] = (ObjectKeyframe) Keyframe.ofObject(1f, values[0]); - } else { - keyframes[0] = (ObjectKeyframe) Keyframe.ofObject(0f, values[0]); - for (int i = 1; i < numKeyframes; ++i) { - keyframes[i] = (ObjectKeyframe) Keyframe.ofObject((float) i / (numKeyframes - 1), values[i]); - } - } - return new KeyframeSet(keyframes); - } - - /** - * Sets the TypeEvaluator to be used when calculating animated values. This object - * is required only for KeyframeSets that are not either IntKeyframeSet or FloatKeyframeSet, - * both of which assume their own evaluator to speed up calculations with those primitive - * types. - * - * @param evaluator The TypeEvaluator to be used to calculate animated values. - */ - public void setEvaluator(TypeEvaluator evaluator) { - mEvaluator = evaluator; - } - - @Override - public KeyframeSet clone() { - ArrayList keyframes = mKeyframes; - int numKeyframes = mKeyframes.size(); - Keyframe[] newKeyframes = new Keyframe[numKeyframes]; - for (int i = 0; i < numKeyframes; ++i) { - newKeyframes[i] = keyframes.get(i).clone(); - } - KeyframeSet newSet = new KeyframeSet(newKeyframes); - return newSet; - } - - /** - * Gets the animated value, given the elapsed fraction of the animation (interpolated by the - * animation's interpolator) and the evaluator used to calculate in-between values. This - * function maps the input fraction to the appropriate keyframe interval and a fraction - * between them and returns the interpolated value. Note that the input fraction may fall - * outside the [0-1] bounds, if the animation's interpolator made that happen (e.g., a - * spring interpolation that might send the fraction past 1.0). We handle this situation by - * just using the two keyframes at the appropriate end when the value is outside those bounds. - * - * @param fraction The elapsed fraction of the animation - * @return The animated value. - */ - public Object getValue(float fraction) { - - // Special-case optimization for the common case of only two keyframes - if (mNumKeyframes == 2) { - if (mInterpolator != null) { - fraction = mInterpolator.getInterpolation(fraction); - } - return mEvaluator.evaluate(fraction, mFirstKeyframe.getValue(), - mLastKeyframe.getValue()); - } - if (fraction <= 0f) { - final Keyframe nextKeyframe = mKeyframes.get(1); - final /*Time*/Interpolator interpolator = nextKeyframe.getInterpolator(); - if (interpolator != null) { - fraction = interpolator.getInterpolation(fraction); - } - final float prevFraction = mFirstKeyframe.getFraction(); - float intervalFraction = (fraction - prevFraction) / - (nextKeyframe.getFraction() - prevFraction); - return mEvaluator.evaluate(intervalFraction, mFirstKeyframe.getValue(), - nextKeyframe.getValue()); - } else if (fraction >= 1f) { - final Keyframe prevKeyframe = mKeyframes.get(mNumKeyframes - 2); - final /*Time*/Interpolator interpolator = mLastKeyframe.getInterpolator(); - if (interpolator != null) { - fraction = interpolator.getInterpolation(fraction); - } - final float prevFraction = prevKeyframe.getFraction(); - float intervalFraction = (fraction - prevFraction) / - (mLastKeyframe.getFraction() - prevFraction); - return mEvaluator.evaluate(intervalFraction, prevKeyframe.getValue(), - mLastKeyframe.getValue()); - } - Keyframe prevKeyframe = mFirstKeyframe; - for (int i = 1; i < mNumKeyframes; ++i) { - Keyframe nextKeyframe = mKeyframes.get(i); - if (fraction < nextKeyframe.getFraction()) { - final /*Time*/Interpolator interpolator = nextKeyframe.getInterpolator(); - if (interpolator != null) { - fraction = interpolator.getInterpolation(fraction); - } - final float prevFraction = prevKeyframe.getFraction(); - float intervalFraction = (fraction - prevFraction) / - (nextKeyframe.getFraction() - prevFraction); - return mEvaluator.evaluate(intervalFraction, prevKeyframe.getValue(), - nextKeyframe.getValue()); - } - prevKeyframe = nextKeyframe; - } - // shouldn't reach here - return mLastKeyframe.getValue(); - } - - @Override - public String toString() { - String returnVal = " "; - for (int i = 0; i < mNumKeyframes; ++i) { - returnVal += mKeyframes.get(i).getValue() + " "; - } - return returnVal; - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/ObjectAnimator.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/ObjectAnimator.java deleted file mode 100644 index 21d15c02a..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/ObjectAnimator.java +++ /dev/null @@ -1,491 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.nineoldandroids.animation; - -import android.util.Log; -//import android.util.Property; - -//import java.lang.reflect.Method; -import java.util.ArrayList; - -/** - * This subclass of {@link ValueAnimator} provides support for animating properties on target objects. - * The constructors of this class take parameters to define the target object that will be animated - * as well as the name of the property that will be animated. Appropriate set/get functions - * are then determined internally and the animation will call these functions as necessary to - * animate the property. - * - * @see #setPropertyName(String) - * - */ -@SuppressWarnings("rawtypes") -public final class ObjectAnimator extends ValueAnimator { - private static final boolean DBG = false; - - // The target object on which the property exists, set in the constructor - private Object mTarget; - - private String mPropertyName; - - //private Property mProperty; - - /** - * Sets the name of the property that will be animated. This name is used to derive - * a setter function that will be called to set animated values. - * For example, a property name of foo will result - * in a call to the function setFoo() on the target object. If either - * valueFrom or valueTo is null, then a getter function will - * also be derived and called. - * - *

For best performance of the mechanism that calls the setter function determined by the - * name of the property being animated, use float or int typed values, - * and make the setter function for those properties have a void return value. This - * will cause the code to take an optimized path for these constrained circumstances. Other - * property types and return types will work, but will have more overhead in processing - * the requests due to normal reflection mechanisms.

- * - *

Note that the setter function derived from this property name - * must take the same parameter type as the - * valueFrom and valueTo properties, otherwise the call to - * the setter function will fail.

- * - *

If this ObjectAnimator has been set up to animate several properties together, - * using more than one PropertyValuesHolder objects, then setting the propertyName simply - * sets the propertyName in the first of those PropertyValuesHolder objects.

- * - * @param propertyName The name of the property being animated. Should not be null. - */ - public void setPropertyName(String propertyName) { - // mValues could be null if this is being constructed piecemeal. Just record the - // propertyName to be used later when setValues() is called if so. - if (mValues != null) { - PropertyValuesHolder valuesHolder = mValues[0]; - String oldName = valuesHolder.getPropertyName(); - valuesHolder.setPropertyName(propertyName); - mValuesMap.remove(oldName); - mValuesMap.put(propertyName, valuesHolder); - } - mPropertyName = propertyName; - // New property/values/target should cause re-initialization prior to starting - mInitialized = false; - } - - /** - * Sets the property that will be animated. Property objects will take precedence over - * properties specified by the {@link #setPropertyName(String)} method. Animations should - * be set up to use one or the other, not both. - * - * @param property The property being animated. Should not be null. - */ - //public void setProperty(Property property) { - // // mValues could be null if this is being constructed piecemeal. Just record the - // // propertyName to be used later when setValues() is called if so. - // if (mValues != null) { - // PropertyValuesHolder valuesHolder = mValues[0]; - // String oldName = valuesHolder.getPropertyName(); - // valuesHolder.setProperty(property); - // mValuesMap.remove(oldName); - // mValuesMap.put(mPropertyName, valuesHolder); - // } - // if (mProperty != null) { - // mPropertyName = property.getName(); - // } - // mProperty = property; - // // New property/values/target should cause re-initialization prior to starting - // mInitialized = false; - //} - - /** - * Gets the name of the property that will be animated. This name will be used to derive - * a setter function that will be called to set animated values. - * For example, a property name of foo will result - * in a call to the function setFoo() on the target object. If either - * valueFrom or valueTo is null, then a getter function will - * also be derived and called. - */ - public String getPropertyName() { - return mPropertyName; - } - - /** - * Creates a new ObjectAnimator object. This default constructor is primarily for - * use internally; the other constructors which take parameters are more generally - * useful. - */ - public ObjectAnimator() { - } - - /** - * Private utility constructor that initializes the target object and name of the - * property being animated. - * - * @param target The object whose property is to be animated. This object should - * have a public method on it called setName(), where name is - * the value of the propertyName parameter. - * @param propertyName The name of the property being animated. - */ - private ObjectAnimator(Object target, String propertyName) { - mTarget = target; - setPropertyName(propertyName); - } - - /** - * Private utility constructor that initializes the target object and property being animated. - * - * @param target The object whose property is to be animated. - * @param property The property being animated. - */ - //private ObjectAnimator(T target, Property property) { - // mTarget = target; - // setProperty(property); - //} - - /** - * Constructs and returns an ObjectAnimator that animates between int values. A single - * value implies that that value is the one being animated to. Two values imply a starting - * and ending values. More than two values imply a starting value, values to animate through - * along the way, and an ending value (these values will be distributed evenly across - * the duration of the animation). - * - * @param target The object whose property is to be animated. This object should - * have a public method on it called setName(), where name is - * the value of the propertyName parameter. - * @param propertyName The name of the property being animated. - * @param values A set of values that the animation will animate between over time. - * @return An ObjectAnimator object that is set up to animate between the given values. - */ - public static ObjectAnimator ofInt(Object target, String propertyName, int... values) { - ObjectAnimator anim = new ObjectAnimator(target, propertyName); - anim.setIntValues(values); - return anim; - } - - /** - * Constructs and returns an ObjectAnimator that animates between int values. A single - * value implies that that value is the one being animated to. Two values imply a starting - * and ending values. More than two values imply a starting value, values to animate through - * along the way, and an ending value (these values will be distributed evenly across - * the duration of the animation). - * - * @param target The object whose property is to be animated. - * @param property The property being animated. - * @param values A set of values that the animation will animate between over time. - * @return An ObjectAnimator object that is set up to animate between the given values. - */ - //public static ObjectAnimator ofInt(T target, Property property, int... values) { - // ObjectAnimator anim = new ObjectAnimator(target, property); - // anim.setIntValues(values); - // return anim; - //} - - /** - * Constructs and returns an ObjectAnimator that animates between float values. A single - * value implies that that value is the one being animated to. Two values imply a starting - * and ending values. More than two values imply a starting value, values to animate through - * along the way, and an ending value (these values will be distributed evenly across - * the duration of the animation). - * - * @param target The object whose property is to be animated. This object should - * have a public method on it called setName(), where name is - * the value of the propertyName parameter. - * @param propertyName The name of the property being animated. - * @param values A set of values that the animation will animate between over time. - * @return An ObjectAnimator object that is set up to animate between the given values. - */ - public static ObjectAnimator ofFloat(Object target, String propertyName, float... values) { - ObjectAnimator anim = new ObjectAnimator(target, propertyName); - anim.setFloatValues(values); - return anim; - } - - /** - * Constructs and returns an ObjectAnimator that animates between float values. A single - * value implies that that value is the one being animated to. Two values imply a starting - * and ending values. More than two values imply a starting value, values to animate through - * along the way, and an ending value (these values will be distributed evenly across - * the duration of the animation). - * - * @param target The object whose property is to be animated. - * @param property The property being animated. - * @param values A set of values that the animation will animate between over time. - * @return An ObjectAnimator object that is set up to animate between the given values. - */ - //public static ObjectAnimator ofFloat(T target, Property property, - // float... values) { - // ObjectAnimator anim = new ObjectAnimator(target, property); - // anim.setFloatValues(values); - // return anim; - //} - - /** - * Constructs and returns an ObjectAnimator that animates between Object values. A single - * value implies that that value is the one being animated to. Two values imply a starting - * and ending values. More than two values imply a starting value, values to animate through - * along the way, and an ending value (these values will be distributed evenly across - * the duration of the animation). - * - * @param target The object whose property is to be animated. This object should - * have a public method on it called setName(), where name is - * the value of the propertyName parameter. - * @param propertyName The name of the property being animated. - * @param evaluator A TypeEvaluator that will be called on each animation frame to - * provide the necessary interpolation between the Object values to derive the animated - * value. - * @param values A set of values that the animation will animate between over time. - * @return An ObjectAnimator object that is set up to animate between the given values. - */ - public static ObjectAnimator ofObject(Object target, String propertyName, - TypeEvaluator evaluator, Object... values) { - ObjectAnimator anim = new ObjectAnimator(target, propertyName); - anim.setObjectValues(values); - anim.setEvaluator(evaluator); - return anim; - } - - /** - * Constructs and returns an ObjectAnimator that animates between Object values. A single - * value implies that that value is the one being animated to. Two values imply a starting - * and ending values. More than two values imply a starting value, values to animate through - * along the way, and an ending value (these values will be distributed evenly across - * the duration of the animation). - * - * @param target The object whose property is to be animated. - * @param property The property being animated. - * @param evaluator A TypeEvaluator that will be called on each animation frame to - * provide the necessary interpolation between the Object values to derive the animated - * value. - * @param values A set of values that the animation will animate between over time. - * @return An ObjectAnimator object that is set up to animate between the given values. - */ - //public static ObjectAnimator ofObject(T target, Property property, - // TypeEvaluator evaluator, V... values) { - // ObjectAnimator anim = new ObjectAnimator(target, property); - // anim.setObjectValues(values); - // anim.setEvaluator(evaluator); - // return anim; - //} - - /** - * Constructs and returns an ObjectAnimator that animates between the sets of values specified - * in PropertyValueHolder objects. This variant should be used when animating - * several properties at once with the same ObjectAnimator, since PropertyValuesHolder allows - * you to associate a set of animation values with a property name. - * - * @param target The object whose property is to be animated. Depending on how the - * PropertyValuesObjects were constructed, the target object should either have the {@link - * android.util.Property} objects used to construct the PropertyValuesHolder objects or (if the - * PropertyValuesHOlder objects were created with property names) the target object should have - * public methods on it called setName(), where name is the name of - * the property passed in as the propertyName parameter for each of the - * PropertyValuesHolder objects. - * @param values A set of PropertyValuesHolder objects whose values will be animated between - * over time. - * @return An ObjectAnimator object that is set up to animate between the given values. - */ - public static ObjectAnimator ofPropertyValuesHolder(Object target, - PropertyValuesHolder... values) { - ObjectAnimator anim = new ObjectAnimator(); - anim.mTarget = target; - anim.setValues(values); - return anim; - } - - @Override - public void setIntValues(int... values) { - if (mValues == null || mValues.length == 0) { - // No values yet - this animator is being constructed piecemeal. Init the values with - // whatever the current propertyName is - //if (mProperty != null) { - // setValues(PropertyValuesHolder.ofInt(mProperty, values)); - //} else { - setValues(PropertyValuesHolder.ofInt(mPropertyName, values)); - //} - } else { - super.setIntValues(values); - } - } - - @Override - public void setFloatValues(float... values) { - if (mValues == null || mValues.length == 0) { - // No values yet - this animator is being constructed piecemeal. Init the values with - // whatever the current propertyName is - //if (mProperty != null) { - // setValues(PropertyValuesHolder.ofFloat(mProperty, values)); - //} else { - setValues(PropertyValuesHolder.ofFloat(mPropertyName, values)); - //} - } else { - super.setFloatValues(values); - } - } - - @Override - public void setObjectValues(Object... values) { - if (mValues == null || mValues.length == 0) { - // No values yet - this animator is being constructed piecemeal. Init the values with - // whatever the current propertyName is - //if (mProperty != null) { - // setValues(PropertyValuesHolder.ofObject(mProperty, (TypeEvaluator)null, values)); - //} else { - setValues(PropertyValuesHolder.ofObject(mPropertyName, (TypeEvaluator)null, values)); - //} - } else { - super.setObjectValues(values); - } - } - - @Override - public void start() { - if (DBG) { - Log.d("ObjectAnimator", "Anim target, duration: " + mTarget + ", " + getDuration()); - for (int i = 0; i < mValues.length; ++i) { - PropertyValuesHolder pvh = mValues[i]; - ArrayList keyframes = pvh.mKeyframeSet.mKeyframes; - Log.d("ObjectAnimator", " Values[" + i + "]: " + - pvh.getPropertyName() + ", " + keyframes.get(0).getValue() + ", " + - keyframes.get(pvh.mKeyframeSet.mNumKeyframes - 1).getValue()); - } - } - super.start(); - } - - /** - * This function is called immediately before processing the first animation - * frame of an animation. If there is a nonzero startDelay, the - * function is called after that delay ends. - * It takes care of the final initialization steps for the - * animation. This includes setting mEvaluator, if the user has not yet - * set it up, and the setter/getter methods, if the user did not supply - * them. - * - *

Overriders of this method should call the superclass method to cause - * internal mechanisms to be set up correctly.

- */ - @Override - void initAnimation() { - if (!mInitialized) { - // mValueType may change due to setter/getter setup; do this before calling super.init(), - // which uses mValueType to set up the default type evaluator. - int numValues = mValues.length; - for (int i = 0; i < numValues; ++i) { - mValues[i].setupSetterAndGetter(mTarget); - } - super.initAnimation(); - } - } - - /** - * Sets the length of the animation. The default duration is 300 milliseconds. - * - * @param duration The length of the animation, in milliseconds. - * @return ObjectAnimator The object called with setDuration(). This return - * value makes it easier to compose statements together that construct and then set the - * duration, as in - * ObjectAnimator.ofInt(target, propertyName, 0, 10).setDuration(500).start(). - */ - @Override - public ObjectAnimator setDuration(long duration) { - super.setDuration(duration); - return this; - } - - - /** - * The target object whose property will be animated by this animation - * - * @return The object being animated - */ - public Object getTarget() { - return mTarget; - } - - /** - * Sets the target object whose property will be animated by this animation - * - * @param target The object being animated - */ - @Override - public void setTarget(Object target) { - if (mTarget != target) { - final Object oldTarget = mTarget; - mTarget = target; - if (oldTarget != null && target != null && oldTarget.getClass() == target.getClass()) { - return; - } - // New target type should cause re-initialization prior to starting - mInitialized = false; - } - } - - @Override - public void setupStartValues() { - initAnimation(); - int numValues = mValues.length; - for (int i = 0; i < numValues; ++i) { - mValues[i].setupStartValue(mTarget); - } - } - - @Override - public void setupEndValues() { - initAnimation(); - int numValues = mValues.length; - for (int i = 0; i < numValues; ++i) { - mValues[i].setupEndValue(mTarget); - } - } - - /** - * This method is called with the elapsed fraction of the animation during every - * animation frame. This function turns the elapsed fraction into an interpolated fraction - * and then into an animated value (from the evaluator. The function is called mostly during - * animation updates, but it is also called when the end() - * function is called, to set the final value on the property. - * - *

Overrides of this method must call the superclass to perform the calculation - * of the animated value.

- * - * @param fraction The elapsed fraction of the animation. - */ - @Override - void animateValue(float fraction) { - super.animateValue(fraction); - int numValues = mValues.length; - for (int i = 0; i < numValues; ++i) { - mValues[i].setAnimatedValue(mTarget); - } - } - - @Override - public ObjectAnimator clone() { - final ObjectAnimator anim = (ObjectAnimator) super.clone(); - return anim; - } - - @Override - public String toString() { - String returnVal = "ObjectAnimator@" + Integer.toHexString(hashCode()) + ", target " + - mTarget; - if (mValues != null) { - for (int i = 0; i < mValues.length; ++i) { - returnVal += "\n " + mValues[i].toString(); - } - } - return returnVal; - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/PropertyValuesHolder.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/PropertyValuesHolder.java deleted file mode 100644 index 84f7504ab..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/PropertyValuesHolder.java +++ /dev/null @@ -1,1012 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.nineoldandroids.animation; - -//import android.util.FloatProperty; -//import android.util.IntProperty; -import android.util.Log; -//import android.util.Property; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.HashMap; -import java.util.concurrent.locks.ReentrantReadWriteLock; - -/** - * This class holds information about a property and the values that that property - * should take on during an animation. PropertyValuesHolder objects can be used to create - * animations with ValueAnimator or ObjectAnimator that operate on several different properties - * in parallel. - */ -@SuppressWarnings({"rawtypes", "unchecked"}) -public class PropertyValuesHolder implements Cloneable { - - /** - * The name of the property associated with the values. This need not be a real property, - * unless this object is being used with ObjectAnimator. But this is the name by which - * aniamted values are looked up with getAnimatedValue(String) in ValueAnimator. - */ - String mPropertyName; - - /** - * @hide - */ - //protected Property mProperty; - - /** - * The setter function, if needed. ObjectAnimator hands off this functionality to - * PropertyValuesHolder, since it holds all of the per-property information. This - * property is automatically - * derived when the animation starts in setupSetterAndGetter() if using ObjectAnimator. - */ - Method mSetter = null; - - /** - * The getter function, if needed. ObjectAnimator hands off this functionality to - * PropertyValuesHolder, since it holds all of the per-property information. This - * property is automatically - * derived when the animation starts in setupSetterAndGetter() if using ObjectAnimator. - * The getter is only derived and used if one of the values is null. - */ - private Method mGetter = null; - - /** - * The type of values supplied. This information is used both in deriving the setter/getter - * functions and in deriving the type of TypeEvaluator. - */ - Class mValueType; - - /** - * The set of keyframes (time/value pairs) that define this animation. - */ - KeyframeSet mKeyframeSet = null; - - - // type evaluators for the primitive types handled by this implementation - private static final TypeEvaluator sIntEvaluator = new IntEvaluator(); - private static final TypeEvaluator sFloatEvaluator = new FloatEvaluator(); - - // We try several different types when searching for appropriate setter/getter functions. - // The caller may have supplied values in a type that does not match the setter/getter - // functions (such as the integers 0 and 1 to represent floating point values for alpha). - // Also, the use of generics in constructors means that we end up with the Object versions - // of primitive types (Float vs. float). But most likely, the setter/getter functions - // will take primitive types instead. - // So we supply an ordered array of other types to try before giving up. - private static Class[] FLOAT_VARIANTS = {float.class, Float.class, double.class, int.class, - Double.class, Integer.class}; - private static Class[] INTEGER_VARIANTS = {int.class, Integer.class, float.class, double.class, - Float.class, Double.class}; - private static Class[] DOUBLE_VARIANTS = {double.class, Double.class, float.class, int.class, - Float.class, Integer.class}; - - // These maps hold all property entries for a particular class. This map - // is used to speed up property/setter/getter lookups for a given class/property - // combination. No need to use reflection on the combination more than once. - private static final HashMap> sSetterPropertyMap = - new HashMap>(); - private static final HashMap> sGetterPropertyMap = - new HashMap>(); - - // This lock is used to ensure that only one thread is accessing the property maps - // at a time. - final ReentrantReadWriteLock mPropertyMapLock = new ReentrantReadWriteLock(); - - // Used to pass single value to varargs parameter in setter invocation - final Object[] mTmpValueArray = new Object[1]; - - /** - * The type evaluator used to calculate the animated values. This evaluator is determined - * automatically based on the type of the start/end objects passed into the constructor, - * but the system only knows about the primitive types int and float. Any other - * type will need to set the evaluator to a custom evaluator for that type. - */ - private TypeEvaluator mEvaluator; - - /** - * The value most recently calculated by calculateValue(). This is set during - * that function and might be retrieved later either by ValueAnimator.animatedValue() or - * by the property-setting logic in ObjectAnimator.animatedValue(). - */ - private Object mAnimatedValue; - - /** - * Internal utility constructor, used by the factory methods to set the property name. - * @param propertyName The name of the property for this holder. - */ - private PropertyValuesHolder(String propertyName) { - mPropertyName = propertyName; - } - - /** - * Internal utility constructor, used by the factory methods to set the property. - * @param property The property for this holder. - */ - //private PropertyValuesHolder(Property property) { - // mProperty = property; - // if (property != null) { - // mPropertyName = property.getName(); - // } - //} - - /** - * Constructs and returns a PropertyValuesHolder with a given property name and - * set of int values. - * @param propertyName The name of the property being animated. - * @param values The values that the named property will animate between. - * @return PropertyValuesHolder The constructed PropertyValuesHolder object. - */ - public static PropertyValuesHolder ofInt(String propertyName, int... values) { - return new IntPropertyValuesHolder(propertyName, values); - } - - /** - * Constructs and returns a PropertyValuesHolder with a given property and - * set of int values. - * @param property The property being animated. Should not be null. - * @param values The values that the property will animate between. - * @return PropertyValuesHolder The constructed PropertyValuesHolder object. - */ - //public static PropertyValuesHolder ofInt(Property property, int... values) { - // return new IntPropertyValuesHolder(property, values); - //} - - /** - * Constructs and returns a PropertyValuesHolder with a given property name and - * set of float values. - * @param propertyName The name of the property being animated. - * @param values The values that the named property will animate between. - * @return PropertyValuesHolder The constructed PropertyValuesHolder object. - */ - public static PropertyValuesHolder ofFloat(String propertyName, float... values) { - return new FloatPropertyValuesHolder(propertyName, values); - } - - /** - * Constructs and returns a PropertyValuesHolder with a given property and - * set of float values. - * @param property The property being animated. Should not be null. - * @param values The values that the property will animate between. - * @return PropertyValuesHolder The constructed PropertyValuesHolder object. - */ - //public static PropertyValuesHolder ofFloat(Property property, float... values) { - // return new FloatPropertyValuesHolder(property, values); - //} - - /** - * Constructs and returns a PropertyValuesHolder with a given property name and - * set of Object values. This variant also takes a TypeEvaluator because the system - * cannot automatically interpolate between objects of unknown type. - * - * @param propertyName The name of the property being animated. - * @param evaluator A TypeEvaluator that will be called on each animation frame to - * provide the necessary interpolation between the Object values to derive the animated - * value. - * @param values The values that the named property will animate between. - * @return PropertyValuesHolder The constructed PropertyValuesHolder object. - */ - public static PropertyValuesHolder ofObject(String propertyName, TypeEvaluator evaluator, - Object... values) { - PropertyValuesHolder pvh = new PropertyValuesHolder(propertyName); - pvh.setObjectValues(values); - pvh.setEvaluator(evaluator); - return pvh; - } - - /** - * Constructs and returns a PropertyValuesHolder with a given property and - * set of Object values. This variant also takes a TypeEvaluator because the system - * cannot automatically interpolate between objects of unknown type. - * - * @param property The property being animated. Should not be null. - * @param evaluator A TypeEvaluator that will be called on each animation frame to - * provide the necessary interpolation between the Object values to derive the animated - * value. - * @param values The values that the property will animate between. - * @return PropertyValuesHolder The constructed PropertyValuesHolder object. - */ - //public static PropertyValuesHolder ofObject(Property property, - // TypeEvaluator evaluator, V... values) { - // PropertyValuesHolder pvh = new PropertyValuesHolder(property); - // pvh.setObjectValues(values); - // pvh.setEvaluator(evaluator); - // return pvh; - //} - - /** - * Constructs and returns a PropertyValuesHolder object with the specified property name and set - * of values. These values can be of any type, but the type should be consistent so that - * an appropriate {@link android.animation.TypeEvaluator} can be found that matches - * the common type. - *

If there is only one value, it is assumed to be the end value of an animation, - * and an initial value will be derived, if possible, by calling a getter function - * on the object. Also, if any value is null, the value will be filled in when the animation - * starts in the same way. This mechanism of automatically getting null values only works - * if the PropertyValuesHolder object is used in conjunction - * {@link ObjectAnimator}, and with a getter function - * derived automatically from propertyName, since otherwise PropertyValuesHolder has - * no way of determining what the value should be. - * @param propertyName The name of the property associated with this set of values. This - * can be the actual property name to be used when using a ObjectAnimator object, or - * just a name used to get animated values, such as if this object is used with an - * ValueAnimator object. - * @param values The set of values to animate between. - */ - public static PropertyValuesHolder ofKeyframe(String propertyName, Keyframe... values) { - KeyframeSet keyframeSet = KeyframeSet.ofKeyframe(values); - if (keyframeSet instanceof IntKeyframeSet) { - return new IntPropertyValuesHolder(propertyName, (IntKeyframeSet) keyframeSet); - } else if (keyframeSet instanceof FloatKeyframeSet) { - return new FloatPropertyValuesHolder(propertyName, (FloatKeyframeSet) keyframeSet); - } - else { - PropertyValuesHolder pvh = new PropertyValuesHolder(propertyName); - pvh.mKeyframeSet = keyframeSet; - pvh.mValueType = values[0].getType(); - return pvh; - } - } - - /** - * Constructs and returns a PropertyValuesHolder object with the specified property and set - * of values. These values can be of any type, but the type should be consistent so that - * an appropriate {@link android.animation.TypeEvaluator} can be found that matches - * the common type. - *

If there is only one value, it is assumed to be the end value of an animation, - * and an initial value will be derived, if possible, by calling the property's - * {@link android.util.Property#get(Object)} function. - * Also, if any value is null, the value will be filled in when the animation - * starts in the same way. This mechanism of automatically getting null values only works - * if the PropertyValuesHolder object is used in conjunction with - * {@link ObjectAnimator}, since otherwise PropertyValuesHolder has - * no way of determining what the value should be. - * @param property The property associated with this set of values. Should not be null. - * @param values The set of values to animate between. - */ - //public static PropertyValuesHolder ofKeyframe(Property property, Keyframe... values) { - // KeyframeSet keyframeSet = KeyframeSet.ofKeyframe(values); - // if (keyframeSet instanceof IntKeyframeSet) { - // return new IntPropertyValuesHolder(property, (IntKeyframeSet) keyframeSet); - // } else if (keyframeSet instanceof FloatKeyframeSet) { - // return new FloatPropertyValuesHolder(property, (FloatKeyframeSet) keyframeSet); - // } - // else { - // PropertyValuesHolder pvh = new PropertyValuesHolder(property); - // pvh.mKeyframeSet = keyframeSet; - // pvh.mValueType = ((Keyframe)values[0]).getType(); - // return pvh; - // } - //} - - /** - * Set the animated values for this object to this set of ints. - * If there is only one value, it is assumed to be the end value of an animation, - * and an initial value will be derived, if possible, by calling a getter function - * on the object. Also, if any value is null, the value will be filled in when the animation - * starts in the same way. This mechanism of automatically getting null values only works - * if the PropertyValuesHolder object is used in conjunction - * {@link ObjectAnimator}, and with a getter function - * derived automatically from propertyName, since otherwise PropertyValuesHolder has - * no way of determining what the value should be. - * - * @param values One or more values that the animation will animate between. - */ - public void setIntValues(int... values) { - mValueType = int.class; - mKeyframeSet = KeyframeSet.ofInt(values); - } - - /** - * Set the animated values for this object to this set of floats. - * If there is only one value, it is assumed to be the end value of an animation, - * and an initial value will be derived, if possible, by calling a getter function - * on the object. Also, if any value is null, the value will be filled in when the animation - * starts in the same way. This mechanism of automatically getting null values only works - * if the PropertyValuesHolder object is used in conjunction - * {@link ObjectAnimator}, and with a getter function - * derived automatically from propertyName, since otherwise PropertyValuesHolder has - * no way of determining what the value should be. - * - * @param values One or more values that the animation will animate between. - */ - public void setFloatValues(float... values) { - mValueType = float.class; - mKeyframeSet = KeyframeSet.ofFloat(values); - } - - /** - * Set the animated values for this object to this set of Keyframes. - * - * @param values One or more values that the animation will animate between. - */ - public void setKeyframes(Keyframe... values) { - int numKeyframes = values.length; - Keyframe keyframes[] = new Keyframe[Math.max(numKeyframes,2)]; - mValueType = values[0].getType(); - for (int i = 0; i < numKeyframes; ++i) { - keyframes[i] = values[i]; - } - mKeyframeSet = new KeyframeSet(keyframes); - } - - /** - * Set the animated values for this object to this set of Objects. - * If there is only one value, it is assumed to be the end value of an animation, - * and an initial value will be derived, if possible, by calling a getter function - * on the object. Also, if any value is null, the value will be filled in when the animation - * starts in the same way. This mechanism of automatically getting null values only works - * if the PropertyValuesHolder object is used in conjunction - * {@link ObjectAnimator}, and with a getter function - * derived automatically from propertyName, since otherwise PropertyValuesHolder has - * no way of determining what the value should be. - * - * @param values One or more values that the animation will animate between. - */ - public void setObjectValues(Object... values) { - mValueType = values[0].getClass(); - mKeyframeSet = KeyframeSet.ofObject(values); - } - - /** - * Determine the setter or getter function using the JavaBeans convention of setFoo or - * getFoo for a property named 'foo'. This function figures out what the name of the - * function should be and uses reflection to find the Method with that name on the - * target object. - * - * @param targetClass The class to search for the method - * @param prefix "set" or "get", depending on whether we need a setter or getter. - * @param valueType The type of the parameter (in the case of a setter). This type - * is derived from the values set on this PropertyValuesHolder. This type is used as - * a first guess at the parameter type, but we check for methods with several different - * types to avoid problems with slight mis-matches between supplied values and actual - * value types used on the setter. - * @return Method the method associated with mPropertyName. - */ - private Method getPropertyFunction(Class targetClass, String prefix, Class valueType) { - // TODO: faster implementation... - Method returnVal = null; - String methodName = getMethodName(prefix, mPropertyName); - Class args[] = null; - if (valueType == null) { - try { - returnVal = targetClass.getMethod(methodName, args); - } catch (NoSuchMethodException e) { - Log.e("PropertyValuesHolder", targetClass.getSimpleName() + " - " + - "Couldn't find no-arg method for property " + mPropertyName + ": " + e); - } - } else { - args = new Class[1]; - Class typeVariants[]; - if (mValueType.equals(Float.class)) { - typeVariants = FLOAT_VARIANTS; - } else if (mValueType.equals(Integer.class)) { - typeVariants = INTEGER_VARIANTS; - } else if (mValueType.equals(Double.class)) { - typeVariants = DOUBLE_VARIANTS; - } else { - typeVariants = new Class[1]; - typeVariants[0] = mValueType; - } - for (Class typeVariant : typeVariants) { - args[0] = typeVariant; - try { - returnVal = targetClass.getMethod(methodName, args); - // change the value type to suit - mValueType = typeVariant; - return returnVal; - } catch (NoSuchMethodException e) { - // Swallow the error and keep trying other variants - } - } - // If we got here, then no appropriate function was found - Log.e("PropertyValuesHolder", - "Couldn't find " + prefix + "ter property " + mPropertyName + - " for " + targetClass.getSimpleName() + - " with value type "+ mValueType); - } - - return returnVal; - } - - - /** - * Returns the setter or getter requested. This utility function checks whether the - * requested method exists in the propertyMapMap cache. If not, it calls another - * utility function to request the Method from the targetClass directly. - * @param targetClass The Class on which the requested method should exist. - * @param propertyMapMap The cache of setters/getters derived so far. - * @param prefix "set" or "get", for the setter or getter. - * @param valueType The type of parameter passed into the method (null for getter). - * @return Method the method associated with mPropertyName. - */ - private Method setupSetterOrGetter(Class targetClass, - HashMap> propertyMapMap, - String prefix, Class valueType) { - Method setterOrGetter = null; - try { - // Have to lock property map prior to reading it, to guard against - // another thread putting something in there after we've checked it - // but before we've added an entry to it - mPropertyMapLock.writeLock().lock(); - HashMap propertyMap = propertyMapMap.get(targetClass); - if (propertyMap != null) { - setterOrGetter = propertyMap.get(mPropertyName); - } - if (setterOrGetter == null) { - setterOrGetter = getPropertyFunction(targetClass, prefix, valueType); - if (propertyMap == null) { - propertyMap = new HashMap(); - propertyMapMap.put(targetClass, propertyMap); - } - propertyMap.put(mPropertyName, setterOrGetter); - } - } finally { - mPropertyMapLock.writeLock().unlock(); - } - return setterOrGetter; - } - - /** - * Utility function to get the setter from targetClass - * @param targetClass The Class on which the requested method should exist. - */ - void setupSetter(Class targetClass) { - mSetter = setupSetterOrGetter(targetClass, sSetterPropertyMap, "set", mValueType); - } - - /** - * Utility function to get the getter from targetClass - */ - private void setupGetter(Class targetClass) { - mGetter = setupSetterOrGetter(targetClass, sGetterPropertyMap, "get", null); - } - - /** - * Internal function (called from ObjectAnimator) to set up the setter and getter - * prior to running the animation. If the setter has not been manually set for this - * object, it will be derived automatically given the property name, target object, and - * types of values supplied. If no getter has been set, it will be supplied iff any of the - * supplied values was null. If there is a null value, then the getter (supplied or derived) - * will be called to set those null values to the current value of the property - * on the target object. - * @param target The object on which the setter (and possibly getter) exist. - */ - void setupSetterAndGetter(Object target) { - //if (mProperty != null) { - // // check to make sure that mProperty is on the class of target - // try { - // Object testValue = mProperty.get(target); - // for (Keyframe kf : mKeyframeSet.mKeyframes) { - // if (!kf.hasValue()) { - // kf.setValue(mProperty.get(target)); - // } - // } - // return; - // } catch (ClassCastException e) { - // Log.e("PropertyValuesHolder","No such property (" + mProperty.getName() + - // ") on target object " + target + ". Trying reflection instead"); - // mProperty = null; - // } - //} - Class targetClass = target.getClass(); - if (mSetter == null) { - setupSetter(targetClass); - } - for (Keyframe kf : mKeyframeSet.mKeyframes) { - if (!kf.hasValue()) { - if (mGetter == null) { - setupGetter(targetClass); - } - try { - kf.setValue(mGetter.invoke(target)); - } catch (InvocationTargetException e) { - Log.e("PropertyValuesHolder", e.toString()); - } catch (IllegalAccessException e) { - Log.e("PropertyValuesHolder", e.toString()); - } - } - } - } - - /** - * Utility function to set the value stored in a particular Keyframe. The value used is - * whatever the value is for the property name specified in the keyframe on the target object. - * - * @param target The target object from which the current value should be extracted. - * @param kf The keyframe which holds the property name and value. - */ - private void setupValue(Object target, Keyframe kf) { - //if (mProperty != null) { - // kf.setValue(mProperty.get(target)); - //} - try { - if (mGetter == null) { - Class targetClass = target.getClass(); - setupGetter(targetClass); - } - kf.setValue(mGetter.invoke(target)); - } catch (InvocationTargetException e) { - Log.e("PropertyValuesHolder", e.toString()); - } catch (IllegalAccessException e) { - Log.e("PropertyValuesHolder", e.toString()); - } - } - - /** - * This function is called by ObjectAnimator when setting the start values for an animation. - * The start values are set according to the current values in the target object. The - * property whose value is extracted is whatever is specified by the propertyName of this - * PropertyValuesHolder object. - * - * @param target The object which holds the start values that should be set. - */ - void setupStartValue(Object target) { - setupValue(target, mKeyframeSet.mKeyframes.get(0)); - } - - /** - * This function is called by ObjectAnimator when setting the end values for an animation. - * The end values are set according to the current values in the target object. The - * property whose value is extracted is whatever is specified by the propertyName of this - * PropertyValuesHolder object. - * - * @param target The object which holds the start values that should be set. - */ - void setupEndValue(Object target) { - setupValue(target, mKeyframeSet.mKeyframes.get(mKeyframeSet.mKeyframes.size() - 1)); - } - - @Override - public PropertyValuesHolder clone() { - try { - PropertyValuesHolder newPVH = (PropertyValuesHolder) super.clone(); - newPVH.mPropertyName = mPropertyName; - //newPVH.mProperty = mProperty; - newPVH.mKeyframeSet = mKeyframeSet.clone(); - newPVH.mEvaluator = mEvaluator; - return newPVH; - } catch (CloneNotSupportedException e) { - // won't reach here - return null; - } - } - - /** - * Internal function to set the value on the target object, using the setter set up - * earlier on this PropertyValuesHolder object. This function is called by ObjectAnimator - * to handle turning the value calculated by ValueAnimator into a value set on the object - * according to the name of the property. - * @param target The target object on which the value is set - */ - void setAnimatedValue(Object target) { - //if (mProperty != null) { - // mProperty.set(target, getAnimatedValue()); - //} - if (mSetter != null) { - try { - mTmpValueArray[0] = getAnimatedValue(); - mSetter.invoke(target, mTmpValueArray); - } catch (InvocationTargetException e) { - Log.e("PropertyValuesHolder", e.toString()); - } catch (IllegalAccessException e) { - Log.e("PropertyValuesHolder", e.toString()); - } - } - } - - /** - * Internal function, called by ValueAnimator, to set up the TypeEvaluator that will be used - * to calculate animated values. - */ - void init() { - if (mEvaluator == null) { - // We already handle int and float automatically, but not their Object - // equivalents - mEvaluator = (mValueType == Integer.class) ? sIntEvaluator : - (mValueType == Float.class) ? sFloatEvaluator : - null; - } - if (mEvaluator != null) { - // KeyframeSet knows how to evaluate the common types - only give it a custom - // evaluator if one has been set on this class - mKeyframeSet.setEvaluator(mEvaluator); - } - } - - /** - * The TypeEvaluator will the automatically determined based on the type of values - * supplied to PropertyValuesHolder. The evaluator can be manually set, however, if so - * desired. This may be important in cases where either the type of the values supplied - * do not match the way that they should be interpolated between, or if the values - * are of a custom type or one not currently understood by the animation system. Currently, - * only values of type float and int (and their Object equivalents: Float - * and Integer) are correctly interpolated; all other types require setting a TypeEvaluator. - * @param evaluator - */ - public void setEvaluator(TypeEvaluator evaluator) { - mEvaluator = evaluator; - mKeyframeSet.setEvaluator(evaluator); - } - - /** - * Function used to calculate the value according to the evaluator set up for - * this PropertyValuesHolder object. This function is called by ValueAnimator.animateValue(). - * - * @param fraction The elapsed, interpolated fraction of the animation. - */ - void calculateValue(float fraction) { - mAnimatedValue = mKeyframeSet.getValue(fraction); - } - - /** - * Sets the name of the property that will be animated. This name is used to derive - * a setter function that will be called to set animated values. - * For example, a property name of foo will result - * in a call to the function setFoo() on the target object. If either - * valueFrom or valueTo is null, then a getter function will - * also be derived and called. - * - *

Note that the setter function derived from this property name - * must take the same parameter type as the - * valueFrom and valueTo properties, otherwise the call to - * the setter function will fail.

- * - * @param propertyName The name of the property being animated. - */ - public void setPropertyName(String propertyName) { - mPropertyName = propertyName; - } - - /** - * Sets the property that will be animated. - * - *

Note that if this PropertyValuesHolder object is used with ObjectAnimator, the property - * must exist on the target object specified in that ObjectAnimator.

- * - * @param property The property being animated. - */ - //public void setProperty(Property property) { - // mProperty = property; - //} - - /** - * Gets the name of the property that will be animated. This name will be used to derive - * a setter function that will be called to set animated values. - * For example, a property name of foo will result - * in a call to the function setFoo() on the target object. If either - * valueFrom or valueTo is null, then a getter function will - * also be derived and called. - */ - public String getPropertyName() { - return mPropertyName; - } - - /** - * Internal function, called by ValueAnimator and ObjectAnimator, to retrieve the value - * most recently calculated in calculateValue(). - * @return - */ - Object getAnimatedValue() { - return mAnimatedValue; - } - - @Override - public String toString() { - return mPropertyName + ": " + mKeyframeSet.toString(); - } - - /** - * Utility method to derive a setter/getter method name from a property name, where the - * prefix is typically "set" or "get" and the first letter of the property name is - * capitalized. - * - * @param prefix The precursor to the method name, before the property name begins, typically - * "set" or "get". - * @param propertyName The name of the property that represents the bulk of the method name - * after the prefix. The first letter of this word will be capitalized in the resulting - * method name. - * @return String the property name converted to a method name according to the conventions - * specified above. - */ - static String getMethodName(String prefix, String propertyName) { - if (propertyName == null || propertyName.length() == 0) { - // shouldn't get here - return prefix; - } - char firstLetter = Character.toUpperCase(propertyName.charAt(0)); - String theRest = propertyName.substring(1); - return prefix + firstLetter + theRest; - } - - static class IntPropertyValuesHolder extends PropertyValuesHolder { - - // Cache JNI functions to avoid looking them up twice - //private static final HashMap> sJNISetterPropertyMap = - // new HashMap>(); - //int mJniSetter; - //private IntProperty mIntProperty; - - IntKeyframeSet mIntKeyframeSet; - int mIntAnimatedValue; - - public IntPropertyValuesHolder(String propertyName, IntKeyframeSet keyframeSet) { - super(propertyName); - mValueType = int.class; - mKeyframeSet = keyframeSet; - mIntKeyframeSet = (IntKeyframeSet) mKeyframeSet; - } - - //public IntPropertyValuesHolder(Property property, IntKeyframeSet keyframeSet) { - // super(property); - // mValueType = int.class; - // mKeyframeSet = keyframeSet; - // mIntKeyframeSet = (IntKeyframeSet) mKeyframeSet; - // if (property instanceof IntProperty) { - // mIntProperty = (IntProperty) mProperty; - // } - //} - - public IntPropertyValuesHolder(String propertyName, int... values) { - super(propertyName); - setIntValues(values); - } - - //public IntPropertyValuesHolder(Property property, int... values) { - // super(property); - // setIntValues(values); - // if (property instanceof IntProperty) { - // mIntProperty = (IntProperty) mProperty; - // } - //} - - @Override - public void setIntValues(int... values) { - super.setIntValues(values); - mIntKeyframeSet = (IntKeyframeSet) mKeyframeSet; - } - - @Override - void calculateValue(float fraction) { - mIntAnimatedValue = mIntKeyframeSet.getIntValue(fraction); - } - - @Override - Object getAnimatedValue() { - return mIntAnimatedValue; - } - - @Override - public IntPropertyValuesHolder clone() { - IntPropertyValuesHolder newPVH = (IntPropertyValuesHolder) super.clone(); - newPVH.mIntKeyframeSet = (IntKeyframeSet) newPVH.mKeyframeSet; - return newPVH; - } - - /** - * Internal function to set the value on the target object, using the setter set up - * earlier on this PropertyValuesHolder object. This function is called by ObjectAnimator - * to handle turning the value calculated by ValueAnimator into a value set on the object - * according to the name of the property. - * @param target The target object on which the value is set - */ - @Override - void setAnimatedValue(Object target) { - //if (mIntProperty != null) { - // mIntProperty.setValue(target, mIntAnimatedValue); - // return; - //} - //if (mProperty != null) { - // mProperty.set(target, mIntAnimatedValue); - // return; - //} - //if (mJniSetter != 0) { - // nCallIntMethod(target, mJniSetter, mIntAnimatedValue); - // return; - //} - if (mSetter != null) { - try { - mTmpValueArray[0] = mIntAnimatedValue; - mSetter.invoke(target, mTmpValueArray); - } catch (InvocationTargetException e) { - Log.e("PropertyValuesHolder", e.toString()); - } catch (IllegalAccessException e) { - Log.e("PropertyValuesHolder", e.toString()); - } - } - } - - @Override - void setupSetter(Class targetClass) { - //if (mProperty != null) { - // return; - //} - // Check new static hashmap for setter method - //try { - // mPropertyMapLock.writeLock().lock(); - // HashMap propertyMap = sJNISetterPropertyMap.get(targetClass); - // if (propertyMap != null) { - // Integer mJniSetterInteger = propertyMap.get(mPropertyName); - // if (mJniSetterInteger != null) { - // mJniSetter = mJniSetterInteger; - // } - // } - // if (mJniSetter == 0) { - // String methodName = getMethodName("set", mPropertyName); - // mJniSetter = nGetIntMethod(targetClass, methodName); - // if (mJniSetter != 0) { - // if (propertyMap == null) { - // propertyMap = new HashMap(); - // sJNISetterPropertyMap.put(targetClass, propertyMap); - // } - // propertyMap.put(mPropertyName, mJniSetter); - // } - // } - //} catch (NoSuchMethodError e) { - // Log.d("PropertyValuesHolder", - // "Can't find native method using JNI, use reflection" + e); - //} finally { - // mPropertyMapLock.writeLock().unlock(); - //} - //if (mJniSetter == 0) { - // Couldn't find method through fast JNI approach - just use reflection - super.setupSetter(targetClass); - //} - } - } - - static class FloatPropertyValuesHolder extends PropertyValuesHolder { - - // Cache JNI functions to avoid looking them up twice - //private static final HashMap> sJNISetterPropertyMap = - // new HashMap>(); - //int mJniSetter; - //private FloatProperty mFloatProperty; - - FloatKeyframeSet mFloatKeyframeSet; - float mFloatAnimatedValue; - - public FloatPropertyValuesHolder(String propertyName, FloatKeyframeSet keyframeSet) { - super(propertyName); - mValueType = float.class; - mKeyframeSet = keyframeSet; - mFloatKeyframeSet = (FloatKeyframeSet) mKeyframeSet; - } - - //public FloatPropertyValuesHolder(Property property, FloatKeyframeSet keyframeSet) { - // super(property); - // mValueType = float.class; - // mKeyframeSet = keyframeSet; - // mFloatKeyframeSet = (FloatKeyframeSet) mKeyframeSet; - // if (property instanceof FloatProperty) { - // mFloatProperty = (FloatProperty) mProperty; - // } - //} - - public FloatPropertyValuesHolder(String propertyName, float... values) { - super(propertyName); - setFloatValues(values); - } - - //public FloatPropertyValuesHolder(Property property, float... values) { - // super(property); - // setFloatValues(values); - // if (property instanceof FloatProperty) { - // mFloatProperty = (FloatProperty) mProperty; - // } - //} - - @Override - public void setFloatValues(float... values) { - super.setFloatValues(values); - mFloatKeyframeSet = (FloatKeyframeSet) mKeyframeSet; - } - - @Override - void calculateValue(float fraction) { - mFloatAnimatedValue = mFloatKeyframeSet.getFloatValue(fraction); - } - - @Override - Object getAnimatedValue() { - return mFloatAnimatedValue; - } - - @Override - public FloatPropertyValuesHolder clone() { - FloatPropertyValuesHolder newPVH = (FloatPropertyValuesHolder) super.clone(); - newPVH.mFloatKeyframeSet = (FloatKeyframeSet) newPVH.mKeyframeSet; - return newPVH; - } - - /** - * Internal function to set the value on the target object, using the setter set up - * earlier on this PropertyValuesHolder object. This function is called by ObjectAnimator - * to handle turning the value calculated by ValueAnimator into a value set on the object - * according to the name of the property. - * @param target The target object on which the value is set - */ - @Override - void setAnimatedValue(Object target) { - //if (mFloatProperty != null) { - // mFloatProperty.setValue(target, mFloatAnimatedValue); - // return; - //} - //if (mProperty != null) { - // mProperty.set(target, mFloatAnimatedValue); - // return; - //} - //if (mJniSetter != 0) { - // nCallFloatMethod(target, mJniSetter, mFloatAnimatedValue); - // return; - //} - if (mSetter != null) { - try { - mTmpValueArray[0] = mFloatAnimatedValue; - mSetter.invoke(target, mTmpValueArray); - } catch (InvocationTargetException e) { - Log.e("PropertyValuesHolder", e.toString()); - } catch (IllegalAccessException e) { - Log.e("PropertyValuesHolder", e.toString()); - } - } - } - - @Override - void setupSetter(Class targetClass) { - //if (mProperty != null) { - // return; - //} - // Check new static hashmap for setter method - //try { - // mPropertyMapLock.writeLock().lock(); - // HashMap propertyMap = sJNISetterPropertyMap.get(targetClass); - // if (propertyMap != null) { - // Integer mJniSetterInteger = propertyMap.get(mPropertyName); - // if (mJniSetterInteger != null) { - // mJniSetter = mJniSetterInteger; - // } - // } - // if (mJniSetter == 0) { - // String methodName = getMethodName("set", mPropertyName); - // mJniSetter = nGetFloatMethod(targetClass, methodName); - // if (mJniSetter != 0) { - // if (propertyMap == null) { - // propertyMap = new HashMap(); - // sJNISetterPropertyMap.put(targetClass, propertyMap); - // } - // propertyMap.put(mPropertyName, mJniSetter); - // } - // } - //} catch (NoSuchMethodError e) { - // Log.d("PropertyValuesHolder", - // "Can't find native method using JNI, use reflection" + e); - //} finally { - // mPropertyMapLock.writeLock().unlock(); - //} - //if (mJniSetter == 0) { - // Couldn't find method through fast JNI approach - just use reflection - super.setupSetter(targetClass); - //} - } - - } - - //native static private int nGetIntMethod(Class targetClass, String methodName); - //native static private int nGetFloatMethod(Class targetClass, String methodName); - //native static private void nCallIntMethod(Object target, int methodID, int arg); - //native static private void nCallFloatMethod(Object target, int methodID, float arg); -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/TypeEvaluator.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/TypeEvaluator.java deleted file mode 100644 index 0ea319244..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/TypeEvaluator.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.nineoldandroids.animation; - -/** - * Interface for use with the {@link ValueAnimator#setEvaluator(TypeEvaluator)} function. Evaluators - * allow developers to create animations on arbitrary property types, by allowing them to supply - * custom evaulators for types that are not automatically understood and used by the animation - * system. - * - * @see ValueAnimator#setEvaluator(TypeEvaluator) - */ -public interface TypeEvaluator { - - /** - * This function returns the result of linearly interpolating the start and end values, with - * fraction representing the proportion between the start and end values. The - * calculation is a simple parametric calculation: result = x0 + t * (v1 - v0), - * where x0 is startValue, x1 is endValue, - * and t is fraction. - * - * @param fraction The fraction from the starting to the ending values - * @param startValue The start value. - * @param endValue The end value. - * @return A linear interpolation between the start and end values, given the - * fraction parameter. - */ - public T evaluate(float fraction, T startValue, T endValue); - -} \ No newline at end of file diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/ValueAnimator.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/ValueAnimator.java deleted file mode 100644 index d8a12c688..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/ValueAnimator.java +++ /dev/null @@ -1,1265 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.nineoldandroids.animation; - -import android.os.Handler; -import android.os.Looper; -import android.os.Message; -import android.util.AndroidRuntimeException; -import android.view.animation.AccelerateDecelerateInterpolator; -import android.view.animation.AnimationUtils; -import android.view.animation.Interpolator; -import android.view.animation.LinearInterpolator; - -import java.util.ArrayList; -import java.util.HashMap; - -/** - * This class provides a simple timing engine for running animations - * which calculate animated values and set them on target objects. - * - *

There is a single timing pulse that all animations use. It runs in a - * custom handler to ensure that property changes happen on the UI thread.

- * - *

By default, ValueAnimator uses non-linear time interpolation, via the - * {@link AccelerateDecelerateInterpolator} class, which accelerates into and decelerates - * out of an animation. This behavior can be changed by calling - * {@link ValueAnimator#setInterpolator(TimeInterpolator)}.

- */ -@SuppressWarnings({"rawtypes", "unchecked"}) -public class ValueAnimator extends Animator { - - /** - * Internal constants - */ - - /* - * The default amount of time in ms between animation frames - */ - private static final long DEFAULT_FRAME_DELAY = 10; - - /** - * Messages sent to timing handler: START is sent when an animation first begins, FRAME is sent - * by the handler to itself to process the next animation frame - */ - static final int ANIMATION_START = 0; - static final int ANIMATION_FRAME = 1; - - /** - * Values used with internal variable mPlayingState to indicate the current state of an - * animation. - */ - static final int STOPPED = 0; // Not yet playing - static final int RUNNING = 1; // Playing normally - static final int SEEKED = 2; // Seeked to some time value - - /** - * Internal variables - * NOTE: This object implements the clone() method, making a deep copy of any referenced - * objects. As other non-trivial fields are added to this class, make sure to add logic - * to clone() to make deep copies of them. - */ - - // The first time that the animation's animateFrame() method is called. This time is used to - // determine elapsed time (and therefore the elapsed fraction) in subsequent calls - // to animateFrame() - long mStartTime; - - /** - * Set when setCurrentPlayTime() is called. If negative, animation is not currently seeked - * to a value. - */ - long mSeekTime = -1; - - // TODO: We access the following ThreadLocal variables often, some of them on every update. - // If ThreadLocal access is significantly expensive, we may want to put all of these - // fields into a structure sot hat we just access ThreadLocal once to get the reference - // to that structure, then access the structure directly for each field. - - // The static sAnimationHandler processes the internal timing loop on which all animations - // are based - private static ThreadLocal sAnimationHandler = - new ThreadLocal(); - - // The per-thread list of all active animations - private static final ThreadLocal> sAnimations = - new ThreadLocal>() { - @Override - protected ArrayList initialValue() { - return new ArrayList(); - } - }; - - // The per-thread set of animations to be started on the next animation frame - private static final ThreadLocal> sPendingAnimations = - new ThreadLocal>() { - @Override - protected ArrayList initialValue() { - return new ArrayList(); - } - }; - - /** - * Internal per-thread collections used to avoid set collisions as animations start and end - * while being processed. - */ - private static final ThreadLocal> sDelayedAnims = - new ThreadLocal>() { - @Override - protected ArrayList initialValue() { - return new ArrayList(); - } - }; - - private static final ThreadLocal> sEndingAnims = - new ThreadLocal>() { - @Override - protected ArrayList initialValue() { - return new ArrayList(); - } - }; - - private static final ThreadLocal> sReadyAnims = - new ThreadLocal>() { - @Override - protected ArrayList initialValue() { - return new ArrayList(); - } - }; - - // The time interpolator to be used if none is set on the animation - private static final /*Time*/Interpolator sDefaultInterpolator = - new AccelerateDecelerateInterpolator(); - - // type evaluators for the primitive types handled by this implementation - //private static final TypeEvaluator sIntEvaluator = new IntEvaluator(); - //private static final TypeEvaluator sFloatEvaluator = new FloatEvaluator(); - - /** - * Used to indicate whether the animation is currently playing in reverse. This causes the - * elapsed fraction to be inverted to calculate the appropriate values. - */ - private boolean mPlayingBackwards = false; - - /** - * This variable tracks the current iteration that is playing. When mCurrentIteration exceeds the - * repeatCount (if repeatCount!=INFINITE), the animation ends - */ - private int mCurrentIteration = 0; - - /** - * Tracks current elapsed/eased fraction, for querying in getAnimatedFraction(). - */ - private float mCurrentFraction = 0f; - - /** - * Tracks whether a startDelay'd animation has begun playing through the startDelay. - */ - private boolean mStartedDelay = false; - - /** - * Tracks the time at which the animation began playing through its startDelay. This is - * different from the mStartTime variable, which is used to track when the animation became - * active (which is when the startDelay expired and the animation was added to the active - * animations list). - */ - private long mDelayStartTime; - - /** - * Flag that represents the current state of the animation. Used to figure out when to start - * an animation (if state == STOPPED). Also used to end an animation that - * has been cancel()'d or end()'d since the last animation frame. Possible values are - * STOPPED, RUNNING, SEEKED. - */ - int mPlayingState = STOPPED; - - /** - * Additional playing state to indicate whether an animator has been start()'d. There is - * some lag between a call to start() and the first animation frame. We should still note - * that the animation has been started, even if it's first animation frame has not yet - * happened, and reflect that state in isRunning(). - * Note that delayed animations are different: they are not started until their first - * animation frame, which occurs after their delay elapses. - */ - private boolean mRunning = false; - - /** - * Additional playing state to indicate whether an animator has been start()'d, whether or - * not there is a nonzero startDelay. - */ - private boolean mStarted = false; - - /** - * Flag that denotes whether the animation is set up and ready to go. Used to - * set up animation that has not yet been started. - */ - boolean mInitialized = false; - - // - // Backing variables - // - - // How long the animation should last in ms - private long mDuration = 300; - - // The amount of time in ms to delay starting the animation after start() is called - private long mStartDelay = 0; - - // The number of milliseconds between animation frames - private static long sFrameDelay = DEFAULT_FRAME_DELAY; - - // The number of times the animation will repeat. The default is 0, which means the animation - // will play only once - private int mRepeatCount = 0; - - /** - * The type of repetition that will occur when repeatMode is nonzero. RESTART means the - * animation will start from the beginning on every new cycle. REVERSE means the animation - * will reverse directions on each iteration. - */ - private int mRepeatMode = RESTART; - - /** - * The time interpolator to be used. The elapsed fraction of the animation will be passed - * through this interpolator to calculate the interpolated fraction, which is then used to - * calculate the animated values. - */ - private /*Time*/Interpolator mInterpolator = sDefaultInterpolator; - - /** - * The set of listeners to be sent events through the life of an animation. - */ - private ArrayList mUpdateListeners = null; - - /** - * The property/value sets being animated. - */ - PropertyValuesHolder[] mValues; - - /** - * A hashmap of the PropertyValuesHolder objects. This map is used to lookup animated values - * by property name during calls to getAnimatedValue(String). - */ - HashMap mValuesMap; - - /** - * Public constants - */ - - /** - * When the animation reaches the end and repeatCount is INFINITE - * or a positive value, the animation restarts from the beginning. - */ - public static final int RESTART = 1; - /** - * When the animation reaches the end and repeatCount is INFINITE - * or a positive value, the animation reverses direction on every iteration. - */ - public static final int REVERSE = 2; - /** - * This value used used with the {@link #setRepeatCount(int)} property to repeat - * the animation indefinitely. - */ - public static final int INFINITE = -1; - - /** - * Creates a new ValueAnimator object. This default constructor is primarily for - * use internally; the factory methods which take parameters are more generally - * useful. - */ - public ValueAnimator() { - } - - /** - * Constructs and returns a ValueAnimator that animates between int values. A single - * value implies that that value is the one being animated to. However, this is not typically - * useful in a ValueAnimator object because there is no way for the object to determine the - * starting value for the animation (unlike ObjectAnimator, which can derive that value - * from the target object and property being animated). Therefore, there should typically - * be two or more values. - * - * @param values A set of values that the animation will animate between over time. - * @return A ValueAnimator object that is set up to animate between the given values. - */ - public static ValueAnimator ofInt(int... values) { - ValueAnimator anim = new ValueAnimator(); - anim.setIntValues(values); - return anim; - } - - /** - * Constructs and returns a ValueAnimator that animates between float values. A single - * value implies that that value is the one being animated to. However, this is not typically - * useful in a ValueAnimator object because there is no way for the object to determine the - * starting value for the animation (unlike ObjectAnimator, which can derive that value - * from the target object and property being animated). Therefore, there should typically - * be two or more values. - * - * @param values A set of values that the animation will animate between over time. - * @return A ValueAnimator object that is set up to animate between the given values. - */ - public static ValueAnimator ofFloat(float... values) { - ValueAnimator anim = new ValueAnimator(); - anim.setFloatValues(values); - return anim; - } - - /** - * Constructs and returns a ValueAnimator that animates between the values - * specified in the PropertyValuesHolder objects. - * - * @param values A set of PropertyValuesHolder objects whose values will be animated - * between over time. - * @return A ValueAnimator object that is set up to animate between the given values. - */ - public static ValueAnimator ofPropertyValuesHolder(PropertyValuesHolder... values) { - ValueAnimator anim = new ValueAnimator(); - anim.setValues(values); - return anim; - } - /** - * Constructs and returns a ValueAnimator that animates between Object values. A single - * value implies that that value is the one being animated to. However, this is not typically - * useful in a ValueAnimator object because there is no way for the object to determine the - * starting value for the animation (unlike ObjectAnimator, which can derive that value - * from the target object and property being animated). Therefore, there should typically - * be two or more values. - * - *

Since ValueAnimator does not know how to animate between arbitrary Objects, this - * factory method also takes a TypeEvaluator object that the ValueAnimator will use - * to perform that interpolation. - * - * @param evaluator A TypeEvaluator that will be called on each animation frame to - * provide the ncessry interpolation between the Object values to derive the animated - * value. - * @param values A set of values that the animation will animate between over time. - * @return A ValueAnimator object that is set up to animate between the given values. - */ - public static ValueAnimator ofObject(TypeEvaluator evaluator, Object... values) { - ValueAnimator anim = new ValueAnimator(); - anim.setObjectValues(values); - anim.setEvaluator(evaluator); - return anim; - } - - /** - * Sets int values that will be animated between. A single - * value implies that that value is the one being animated to. However, this is not typically - * useful in a ValueAnimator object because there is no way for the object to determine the - * starting value for the animation (unlike ObjectAnimator, which can derive that value - * from the target object and property being animated). Therefore, there should typically - * be two or more values. - * - *

If there are already multiple sets of values defined for this ValueAnimator via more - * than one PropertyValuesHolder object, this method will set the values for the first - * of those objects.

- * - * @param values A set of values that the animation will animate between over time. - */ - public void setIntValues(int... values) { - if (values == null || values.length == 0) { - return; - } - if (mValues == null || mValues.length == 0) { - setValues(new PropertyValuesHolder[]{PropertyValuesHolder.ofInt("", values)}); - } else { - PropertyValuesHolder valuesHolder = mValues[0]; - valuesHolder.setIntValues(values); - } - // New property/values/target should cause re-initialization prior to starting - mInitialized = false; - } - - /** - * Sets float values that will be animated between. A single - * value implies that that value is the one being animated to. However, this is not typically - * useful in a ValueAnimator object because there is no way for the object to determine the - * starting value for the animation (unlike ObjectAnimator, which can derive that value - * from the target object and property being animated). Therefore, there should typically - * be two or more values. - * - *

If there are already multiple sets of values defined for this ValueAnimator via more - * than one PropertyValuesHolder object, this method will set the values for the first - * of those objects.

- * - * @param values A set of values that the animation will animate between over time. - */ - public void setFloatValues(float... values) { - if (values == null || values.length == 0) { - return; - } - if (mValues == null || mValues.length == 0) { - setValues(new PropertyValuesHolder[]{PropertyValuesHolder.ofFloat("", values)}); - } else { - PropertyValuesHolder valuesHolder = mValues[0]; - valuesHolder.setFloatValues(values); - } - // New property/values/target should cause re-initialization prior to starting - mInitialized = false; - } - - /** - * Sets the values to animate between for this animation. A single - * value implies that that value is the one being animated to. However, this is not typically - * useful in a ValueAnimator object because there is no way for the object to determine the - * starting value for the animation (unlike ObjectAnimator, which can derive that value - * from the target object and property being animated). Therefore, there should typically - * be two or more values. - * - *

If there are already multiple sets of values defined for this ValueAnimator via more - * than one PropertyValuesHolder object, this method will set the values for the first - * of those objects.

- * - *

There should be a TypeEvaluator set on the ValueAnimator that knows how to interpolate - * between these value objects. ValueAnimator only knows how to interpolate between the - * primitive types specified in the other setValues() methods.

- * - * @param values The set of values to animate between. - */ - public void setObjectValues(Object... values) { - if (values == null || values.length == 0) { - return; - } - if (mValues == null || mValues.length == 0) { - setValues(new PropertyValuesHolder[]{PropertyValuesHolder.ofObject("", - (TypeEvaluator)null, values)}); - } else { - PropertyValuesHolder valuesHolder = mValues[0]; - valuesHolder.setObjectValues(values); - } - // New property/values/target should cause re-initialization prior to starting - mInitialized = false; - } - - /** - * Sets the values, per property, being animated between. This function is called internally - * by the constructors of ValueAnimator that take a list of values. But an ValueAnimator can - * be constructed without values and this method can be called to set the values manually - * instead. - * - * @param values The set of values, per property, being animated between. - */ - public void setValues(PropertyValuesHolder... values) { - int numValues = values.length; - mValues = values; - mValuesMap = new HashMap(numValues); - for (int i = 0; i < numValues; ++i) { - PropertyValuesHolder valuesHolder = values[i]; - mValuesMap.put(valuesHolder.getPropertyName(), valuesHolder); - } - // New property/values/target should cause re-initialization prior to starting - mInitialized = false; - } - - /** - * Returns the values that this ValueAnimator animates between. These values are stored in - * PropertyValuesHolder objects, even if the ValueAnimator was created with a simple list - * of value objects instead. - * - * @return PropertyValuesHolder[] An array of PropertyValuesHolder objects which hold the - * values, per property, that define the animation. - */ - public PropertyValuesHolder[] getValues() { - return mValues; - } - - /** - * This function is called immediately before processing the first animation - * frame of an animation. If there is a nonzero startDelay, the - * function is called after that delay ends. - * It takes care of the final initialization steps for the - * animation. - * - *

Overrides of this method should call the superclass method to ensure - * that internal mechanisms for the animation are set up correctly.

- */ - void initAnimation() { - if (!mInitialized) { - int numValues = mValues.length; - for (int i = 0; i < numValues; ++i) { - mValues[i].init(); - } - mInitialized = true; - } - } - - - /** - * Sets the length of the animation. The default duration is 300 milliseconds. - * - * @param duration The length of the animation, in milliseconds. This value cannot - * be negative. - * @return ValueAnimator The object called with setDuration(). This return - * value makes it easier to compose statements together that construct and then set the - * duration, as in ValueAnimator.ofInt(0, 10).setDuration(500).start(). - */ - public ValueAnimator setDuration(long duration) { - if (duration < 0) { - throw new IllegalArgumentException("Animators cannot have negative duration: " + - duration); - } - mDuration = duration; - return this; - } - - /** - * Gets the length of the animation. The default duration is 300 milliseconds. - * - * @return The length of the animation, in milliseconds. - */ - public long getDuration() { - return mDuration; - } - - /** - * Sets the position of the animation to the specified point in time. This time should - * be between 0 and the total duration of the animation, including any repetition. If - * the animation has not yet been started, then it will not advance forward after it is - * set to this time; it will simply set the time to this value and perform any appropriate - * actions based on that time. If the animation is already running, then setCurrentPlayTime() - * will set the current playing time to this value and continue playing from that point. - * - * @param playTime The time, in milliseconds, to which the animation is advanced or rewound. - */ - public void setCurrentPlayTime(long playTime) { - initAnimation(); - long currentTime = AnimationUtils.currentAnimationTimeMillis(); - if (mPlayingState != RUNNING) { - mSeekTime = playTime; - mPlayingState = SEEKED; - } - mStartTime = currentTime - playTime; - animationFrame(currentTime); - } - - /** - * Gets the current position of the animation in time, which is equal to the current - * time minus the time that the animation started. An animation that is not yet started will - * return a value of zero. - * - * @return The current position in time of the animation. - */ - public long getCurrentPlayTime() { - if (!mInitialized || mPlayingState == STOPPED) { - return 0; - } - return AnimationUtils.currentAnimationTimeMillis() - mStartTime; - } - - /** - * This custom, static handler handles the timing pulse that is shared by - * all active animations. This approach ensures that the setting of animation - * values will happen on the UI thread and that all animations will share - * the same times for calculating their values, which makes synchronizing - * animations possible. - * - */ - private static class AnimationHandler extends Handler { - /** - * There are only two messages that we care about: ANIMATION_START and - * ANIMATION_FRAME. The START message is sent when an animation's start() - * method is called. It cannot start synchronously when start() is called - * because the call may be on the wrong thread, and it would also not be - * synchronized with other animations because it would not start on a common - * timing pulse. So each animation sends a START message to the handler, which - * causes the handler to place the animation on the active animations queue and - * start processing frames for that animation. - * The FRAME message is the one that is sent over and over while there are any - * active animations to process. - */ - @Override - public void handleMessage(Message msg) { - boolean callAgain = true; - ArrayList animations = sAnimations.get(); - ArrayList delayedAnims = sDelayedAnims.get(); - switch (msg.what) { - // TODO: should we avoid sending frame message when starting if we - // were already running? - case ANIMATION_START: - ArrayList pendingAnimations = sPendingAnimations.get(); - if (animations.size() > 0 || delayedAnims.size() > 0) { - callAgain = false; - } - // pendingAnims holds any animations that have requested to be started - // We're going to clear sPendingAnimations, but starting animation may - // cause more to be added to the pending list (for example, if one animation - // starting triggers another starting). So we loop until sPendingAnimations - // is empty. - while (pendingAnimations.size() > 0) { - ArrayList pendingCopy = - (ArrayList) pendingAnimations.clone(); - pendingAnimations.clear(); - int count = pendingCopy.size(); - for (int i = 0; i < count; ++i) { - ValueAnimator anim = pendingCopy.get(i); - // If the animation has a startDelay, place it on the delayed list - if (anim.mStartDelay == 0) { - anim.startAnimation(); - } else { - delayedAnims.add(anim); - } - } - } - // fall through to process first frame of new animations - case ANIMATION_FRAME: - // currentTime holds the common time for all animations processed - // during this frame - long currentTime = AnimationUtils.currentAnimationTimeMillis(); - ArrayList readyAnims = sReadyAnims.get(); - ArrayList endingAnims = sEndingAnims.get(); - - // First, process animations currently sitting on the delayed queue, adding - // them to the active animations if they are ready - int numDelayedAnims = delayedAnims.size(); - for (int i = 0; i < numDelayedAnims; ++i) { - ValueAnimator anim = delayedAnims.get(i); - if (anim.delayedAnimationFrame(currentTime)) { - readyAnims.add(anim); - } - } - int numReadyAnims = readyAnims.size(); - if (numReadyAnims > 0) { - for (int i = 0; i < numReadyAnims; ++i) { - ValueAnimator anim = readyAnims.get(i); - anim.startAnimation(); - anim.mRunning = true; - delayedAnims.remove(anim); - } - readyAnims.clear(); - } - - // Now process all active animations. The return value from animationFrame() - // tells the handler whether it should now be ended - int numAnims = animations.size(); - int i = 0; - while (i < numAnims) { - ValueAnimator anim = animations.get(i); - if (anim.animationFrame(currentTime)) { - endingAnims.add(anim); - } - if (animations.size() == numAnims) { - ++i; - } else { - // An animation might be canceled or ended by client code - // during the animation frame. Check to see if this happened by - // seeing whether the current index is the same as it was before - // calling animationFrame(). Another approach would be to copy - // animations to a temporary list and process that list instead, - // but that entails garbage and processing overhead that would - // be nice to avoid. - --numAnims; - endingAnims.remove(anim); - } - } - if (endingAnims.size() > 0) { - for (i = 0; i < endingAnims.size(); ++i) { - endingAnims.get(i).endAnimation(); - } - endingAnims.clear(); - } - - // If there are still active or delayed animations, call the handler again - // after the frameDelay - if (callAgain && (!animations.isEmpty() || !delayedAnims.isEmpty())) { - sendEmptyMessageDelayed(ANIMATION_FRAME, Math.max(0, sFrameDelay - - (AnimationUtils.currentAnimationTimeMillis() - currentTime))); - } - break; - } - } - } - - /** - * The amount of time, in milliseconds, to delay starting the animation after - * {@link #start()} is called. - * - * @return the number of milliseconds to delay running the animation - */ - public long getStartDelay() { - return mStartDelay; - } - - /** - * The amount of time, in milliseconds, to delay starting the animation after - * {@link #start()} is called. - - * @param startDelay The amount of the delay, in milliseconds - */ - public void setStartDelay(long startDelay) { - this.mStartDelay = startDelay; - } - - /** - * The amount of time, in milliseconds, between each frame of the animation. This is a - * requested time that the animation will attempt to honor, but the actual delay between - * frames may be different, depending on system load and capabilities. This is a static - * function because the same delay will be applied to all animations, since they are all - * run off of a single timing loop. - * - * @return the requested time between frames, in milliseconds - */ - public static long getFrameDelay() { - return sFrameDelay; - } - - /** - * The amount of time, in milliseconds, between each frame of the animation. This is a - * requested time that the animation will attempt to honor, but the actual delay between - * frames may be different, depending on system load and capabilities. This is a static - * function because the same delay will be applied to all animations, since they are all - * run off of a single timing loop. - * - * @param frameDelay the requested time between frames, in milliseconds - */ - public static void setFrameDelay(long frameDelay) { - sFrameDelay = frameDelay; - } - - /** - * The most recent value calculated by this ValueAnimator when there is just one - * property being animated. This value is only sensible while the animation is running. The main - * purpose for this read-only property is to retrieve the value from the ValueAnimator - * during a call to {@link AnimatorUpdateListener#onAnimationUpdate(ValueAnimator)}, which - * is called during each animation frame, immediately after the value is calculated. - * - * @return animatedValue The value most recently calculated by this ValueAnimator for - * the single property being animated. If there are several properties being animated - * (specified by several PropertyValuesHolder objects in the constructor), this function - * returns the animated value for the first of those objects. - */ - public Object getAnimatedValue() { - if (mValues != null && mValues.length > 0) { - return mValues[0].getAnimatedValue(); - } - // Shouldn't get here; should always have values unless ValueAnimator was set up wrong - return null; - } - - /** - * The most recent value calculated by this ValueAnimator for propertyName. - * The main purpose for this read-only property is to retrieve the value from the - * ValueAnimator during a call to - * {@link AnimatorUpdateListener#onAnimationUpdate(ValueAnimator)}, which - * is called during each animation frame, immediately after the value is calculated. - * - * @return animatedValue The value most recently calculated for the named property - * by this ValueAnimator. - */ - public Object getAnimatedValue(String propertyName) { - PropertyValuesHolder valuesHolder = mValuesMap.get(propertyName); - if (valuesHolder != null) { - return valuesHolder.getAnimatedValue(); - } else { - // At least avoid crashing if called with bogus propertyName - return null; - } - } - - /** - * Sets how many times the animation should be repeated. If the repeat - * count is 0, the animation is never repeated. If the repeat count is - * greater than 0 or {@link #INFINITE}, the repeat mode will be taken - * into account. The repeat count is 0 by default. - * - * @param value the number of times the animation should be repeated - */ - public void setRepeatCount(int value) { - mRepeatCount = value; - } - /** - * Defines how many times the animation should repeat. The default value - * is 0. - * - * @return the number of times the animation should repeat, or {@link #INFINITE} - */ - public int getRepeatCount() { - return mRepeatCount; - } - - /** - * Defines what this animation should do when it reaches the end. This - * setting is applied only when the repeat count is either greater than - * 0 or {@link #INFINITE}. Defaults to {@link #RESTART}. - * - * @param value {@link #RESTART} or {@link #REVERSE} - */ - public void setRepeatMode(int value) { - mRepeatMode = value; - } - - /** - * Defines what this animation should do when it reaches the end. - * - * @return either one of {@link #REVERSE} or {@link #RESTART} - */ - public int getRepeatMode() { - return mRepeatMode; - } - - /** - * Adds a listener to the set of listeners that are sent update events through the life of - * an animation. This method is called on all listeners for every frame of the animation, - * after the values for the animation have been calculated. - * - * @param listener the listener to be added to the current set of listeners for this animation. - */ - public void addUpdateListener(AnimatorUpdateListener listener) { - if (mUpdateListeners == null) { - mUpdateListeners = new ArrayList(); - } - mUpdateListeners.add(listener); - } - - /** - * Removes all listeners from the set listening to frame updates for this animation. - */ - public void removeAllUpdateListeners() { - if (mUpdateListeners == null) { - return; - } - mUpdateListeners.clear(); - mUpdateListeners = null; - } - - /** - * Removes a listener from the set listening to frame updates for this animation. - * - * @param listener the listener to be removed from the current set of update listeners - * for this animation. - */ - public void removeUpdateListener(AnimatorUpdateListener listener) { - if (mUpdateListeners == null) { - return; - } - mUpdateListeners.remove(listener); - if (mUpdateListeners.size() == 0) { - mUpdateListeners = null; - } - } - - - /** - * The time interpolator used in calculating the elapsed fraction of this animation. The - * interpolator determines whether the animation runs with linear or non-linear motion, - * such as acceleration and deceleration. The default value is - * {@link android.view.animation.AccelerateDecelerateInterpolator} - * - * @param value the interpolator to be used by this animation. A value of null - * will result in linear interpolation. - */ - @Override - public void setInterpolator(/*Time*/Interpolator value) { - if (value != null) { - mInterpolator = value; - } else { - mInterpolator = new LinearInterpolator(); - } - } - - /** - * Returns the timing interpolator that this ValueAnimator uses. - * - * @return The timing interpolator for this ValueAnimator. - */ - public /*Time*/Interpolator getInterpolator() { - return mInterpolator; - } - - /** - * The type evaluator to be used when calculating the animated values of this animation. - * The system will automatically assign a float or int evaluator based on the type - * of startValue and endValue in the constructor. But if these values - * are not one of these primitive types, or if different evaluation is desired (such as is - * necessary with int values that represent colors), a custom evaluator needs to be assigned. - * For example, when running an animation on color values, the {@link ArgbEvaluator} - * should be used to get correct RGB color interpolation. - * - *

If this ValueAnimator has only one set of values being animated between, this evaluator - * will be used for that set. If there are several sets of values being animated, which is - * the case if PropertyValuesHOlder objects were set on the ValueAnimator, then the evaluator - * is assigned just to the first PropertyValuesHolder object.

- * - * @param value the evaluator to be used this animation - */ - public void setEvaluator(TypeEvaluator value) { - if (value != null && mValues != null && mValues.length > 0) { - mValues[0].setEvaluator(value); - } - } - - /** - * Start the animation playing. This version of start() takes a boolean flag that indicates - * whether the animation should play in reverse. The flag is usually false, but may be set - * to true if called from the reverse() method. - * - *

The animation started by calling this method will be run on the thread that called - * this method. This thread should have a Looper on it (a runtime exception will be thrown if - * this is not the case). Also, if the animation will animate - * properties of objects in the view hierarchy, then the calling thread should be the UI - * thread for that view hierarchy.

- * - * @param playBackwards Whether the ValueAnimator should start playing in reverse. - */ - private void start(boolean playBackwards) { - if (Looper.myLooper() == null) { - throw new AndroidRuntimeException("Animators may only be run on Looper threads"); - } - mPlayingBackwards = playBackwards; - mCurrentIteration = 0; - mPlayingState = STOPPED; - mStarted = true; - mStartedDelay = false; - sPendingAnimations.get().add(this); - if (mStartDelay == 0) { - // This sets the initial value of the animation, prior to actually starting it running - setCurrentPlayTime(getCurrentPlayTime()); - mPlayingState = STOPPED; - mRunning = true; - - if (mListeners != null) { - ArrayList tmpListeners = - (ArrayList) mListeners.clone(); - int numListeners = tmpListeners.size(); - for (int i = 0; i < numListeners; ++i) { - tmpListeners.get(i).onAnimationStart(this); - } - } - } - AnimationHandler animationHandler = sAnimationHandler.get(); - if (animationHandler == null) { - animationHandler = new AnimationHandler(); - sAnimationHandler.set(animationHandler); - } - animationHandler.sendEmptyMessage(ANIMATION_START); - } - - @Override - public void start() { - start(false); - } - - @Override - public void cancel() { - // Only cancel if the animation is actually running or has been started and is about - // to run - if (mPlayingState != STOPPED || sPendingAnimations.get().contains(this) || - sDelayedAnims.get().contains(this)) { - // Only notify listeners if the animator has actually started - if (mRunning && mListeners != null) { - ArrayList tmpListeners = - (ArrayList) mListeners.clone(); - for (AnimatorListener listener : tmpListeners) { - listener.onAnimationCancel(this); - } - } - endAnimation(); - } - } - - @Override - public void end() { - if (!sAnimations.get().contains(this) && !sPendingAnimations.get().contains(this)) { - // Special case if the animation has not yet started; get it ready for ending - mStartedDelay = false; - startAnimation(); - } else if (!mInitialized) { - initAnimation(); - } - // The final value set on the target varies, depending on whether the animation - // was supposed to repeat an odd number of times - if (mRepeatCount > 0 && (mRepeatCount & 0x01) == 1) { - animateValue(0f); - } else { - animateValue(1f); - } - endAnimation(); - } - - @Override - public boolean isRunning() { - return (mPlayingState == RUNNING || mRunning); - } - - @Override - public boolean isStarted() { - return mStarted; - } - - /** - * Plays the ValueAnimator in reverse. If the animation is already running, - * it will stop itself and play backwards from the point reached when reverse was called. - * If the animation is not currently running, then it will start from the end and - * play backwards. This behavior is only set for the current animation; future playing - * of the animation will use the default behavior of playing forward. - */ - public void reverse() { - mPlayingBackwards = !mPlayingBackwards; - if (mPlayingState == RUNNING) { - long currentTime = AnimationUtils.currentAnimationTimeMillis(); - long currentPlayTime = currentTime - mStartTime; - long timeLeft = mDuration - currentPlayTime; - mStartTime = currentTime - timeLeft; - } else { - start(true); - } - } - - /** - * Called internally to end an animation by removing it from the animations list. Must be - * called on the UI thread. - */ - private void endAnimation() { - sAnimations.get().remove(this); - sPendingAnimations.get().remove(this); - sDelayedAnims.get().remove(this); - mPlayingState = STOPPED; - if (mRunning && mListeners != null) { - ArrayList tmpListeners = - (ArrayList) mListeners.clone(); - int numListeners = tmpListeners.size(); - for (int i = 0; i < numListeners; ++i) { - tmpListeners.get(i).onAnimationEnd(this); - } - } - mRunning = false; - mStarted = false; - } - - /** - * Called internally to start an animation by adding it to the active animations list. Must be - * called on the UI thread. - */ - private void startAnimation() { - initAnimation(); - sAnimations.get().add(this); - if (mStartDelay > 0 && mListeners != null) { - // Listeners were already notified in start() if startDelay is 0; this is - // just for delayed animations - ArrayList tmpListeners = - (ArrayList) mListeners.clone(); - int numListeners = tmpListeners.size(); - for (int i = 0; i < numListeners; ++i) { - tmpListeners.get(i).onAnimationStart(this); - } - } - } - - /** - * Internal function called to process an animation frame on an animation that is currently - * sleeping through its startDelay phase. The return value indicates whether it - * should be woken up and put on the active animations queue. - * - * @param currentTime The current animation time, used to calculate whether the animation - * has exceeded its startDelay and should be started. - * @return True if the animation's startDelay has been exceeded and the animation - * should be added to the set of active animations. - */ - private boolean delayedAnimationFrame(long currentTime) { - if (!mStartedDelay) { - mStartedDelay = true; - mDelayStartTime = currentTime; - } else { - long deltaTime = currentTime - mDelayStartTime; - if (deltaTime > mStartDelay) { - // startDelay ended - start the anim and record the - // mStartTime appropriately - mStartTime = currentTime - (deltaTime - mStartDelay); - mPlayingState = RUNNING; - return true; - } - } - return false; - } - - /** - * This internal function processes a single animation frame for a given animation. The - * currentTime parameter is the timing pulse sent by the handler, used to calculate the - * elapsed duration, and therefore - * the elapsed fraction, of the animation. The return value indicates whether the animation - * should be ended (which happens when the elapsed time of the animation exceeds the - * animation's duration, including the repeatCount). - * - * @param currentTime The current time, as tracked by the static timing handler - * @return true if the animation's duration, including any repetitions due to - * repeatCount has been exceeded and the animation should be ended. - */ - boolean animationFrame(long currentTime) { - boolean done = false; - - if (mPlayingState == STOPPED) { - mPlayingState = RUNNING; - if (mSeekTime < 0) { - mStartTime = currentTime; - } else { - mStartTime = currentTime - mSeekTime; - // Now that we're playing, reset the seek time - mSeekTime = -1; - } - } - switch (mPlayingState) { - case RUNNING: - case SEEKED: - float fraction = mDuration > 0 ? (float)(currentTime - mStartTime) / mDuration : 1f; - if (fraction >= 1f) { - if (mCurrentIteration < mRepeatCount || mRepeatCount == INFINITE) { - // Time to repeat - if (mListeners != null) { - int numListeners = mListeners.size(); - for (int i = 0; i < numListeners; ++i) { - mListeners.get(i).onAnimationRepeat(this); - } - } - if (mRepeatMode == REVERSE) { - mPlayingBackwards = mPlayingBackwards ? false : true; - } - mCurrentIteration += (int)fraction; - fraction = fraction % 1f; - mStartTime += mDuration; - } else { - done = true; - fraction = Math.min(fraction, 1.0f); - } - } - if (mPlayingBackwards) { - fraction = 1f - fraction; - } - animateValue(fraction); - break; - } - - return done; - } - - /** - * Returns the current animation fraction, which is the elapsed/interpolated fraction used in - * the most recent frame update on the animation. - * - * @return Elapsed/interpolated fraction of the animation. - */ - public float getAnimatedFraction() { - return mCurrentFraction; - } - - /** - * This method is called with the elapsed fraction of the animation during every - * animation frame. This function turns the elapsed fraction into an interpolated fraction - * and then into an animated value (from the evaluator. The function is called mostly during - * animation updates, but it is also called when the end() - * function is called, to set the final value on the property. - * - *

Overrides of this method must call the superclass to perform the calculation - * of the animated value.

- * - * @param fraction The elapsed fraction of the animation. - */ - void animateValue(float fraction) { - fraction = mInterpolator.getInterpolation(fraction); - mCurrentFraction = fraction; - int numValues = mValues.length; - for (int i = 0; i < numValues; ++i) { - mValues[i].calculateValue(fraction); - } - if (mUpdateListeners != null) { - int numListeners = mUpdateListeners.size(); - for (int i = 0; i < numListeners; ++i) { - mUpdateListeners.get(i).onAnimationUpdate(this); - } - } - } - - @Override - public ValueAnimator clone() { - final ValueAnimator anim = (ValueAnimator) super.clone(); - if (mUpdateListeners != null) { - ArrayList oldListeners = mUpdateListeners; - anim.mUpdateListeners = new ArrayList(); - int numListeners = oldListeners.size(); - for (int i = 0; i < numListeners; ++i) { - anim.mUpdateListeners.add(oldListeners.get(i)); - } - } - anim.mSeekTime = -1; - anim.mPlayingBackwards = false; - anim.mCurrentIteration = 0; - anim.mInitialized = false; - anim.mPlayingState = STOPPED; - anim.mStartedDelay = false; - PropertyValuesHolder[] oldValues = mValues; - if (oldValues != null) { - int numValues = oldValues.length; - anim.mValues = new PropertyValuesHolder[numValues]; - anim.mValuesMap = new HashMap(numValues); - for (int i = 0; i < numValues; ++i) { - PropertyValuesHolder newValuesHolder = oldValues[i].clone(); - anim.mValues[i] = newValuesHolder; - anim.mValuesMap.put(newValuesHolder.getPropertyName(), newValuesHolder); - } - } - return anim; - } - - /** - * Implementors of this interface can add themselves as update listeners - * to an ValueAnimator instance to receive callbacks on every animation - * frame, after the current frame's values have been calculated for that - * ValueAnimator. - */ - public static interface AnimatorUpdateListener { - /** - *

Notifies the occurrence of another frame of the animation.

- * - * @param animation The animation which was repeated. - */ - void onAnimationUpdate(ValueAnimator animation); - - } - - /** - * Return the number of animations currently running. - * - * Used by StrictMode internally to annotate violations. Only - * called on the main thread. - * - * @hide - */ - public static int getCurrentAnimationsCount() { - return sAnimations.get().size(); - } - - /** - * Clear all animations on this thread, without canceling or ending them. - * This should be used with caution. - * - * @hide - */ - public static void clearAllAnimations() { - sAnimations.get().clear(); - sPendingAnimations.get().clear(); - sDelayedAnims.get().clear(); - } - - @Override - public String toString() { - String returnVal = "ValueAnimator@" + Integer.toHexString(hashCode()); - if (mValues != null) { - for (int i = 0; i < mValues.length; ++i) { - returnVal += "\n " + mValues[i].toString(); - } - } - return returnVal; - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/view/NineViewGroup.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/view/NineViewGroup.java deleted file mode 100644 index 7b830b9c0..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/view/NineViewGroup.java +++ /dev/null @@ -1,79 +0,0 @@ -package com.actionbarsherlock.internal.nineoldandroids.view; - -import android.content.Context; -import android.util.AttributeSet; -import android.view.ViewGroup; - -import com.actionbarsherlock.internal.nineoldandroids.view.animation.AnimatorProxy; - -public abstract class NineViewGroup extends ViewGroup { - private final AnimatorProxy mProxy; - - public NineViewGroup(Context context) { - super(context); - mProxy = AnimatorProxy.NEEDS_PROXY ? AnimatorProxy.wrap(this) : null; - } - public NineViewGroup(Context context, AttributeSet attrs) { - super(context, attrs); - mProxy = AnimatorProxy.NEEDS_PROXY ? AnimatorProxy.wrap(this) : null; - } - public NineViewGroup(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - mProxy = AnimatorProxy.NEEDS_PROXY ? AnimatorProxy.wrap(this) : null; - } - - @Override - public void setVisibility(int visibility) { - if (mProxy != null) { - if (visibility == GONE) { - clearAnimation(); - } else if (visibility == VISIBLE) { - setAnimation(mProxy); - } - } - super.setVisibility(visibility); - } - - public float getAlpha() { - if (AnimatorProxy.NEEDS_PROXY) { - return mProxy.getAlpha(); - } else { - return super.getAlpha(); - } - } - public void setAlpha(float alpha) { - if (AnimatorProxy.NEEDS_PROXY) { - mProxy.setAlpha(alpha); - } else { - super.setAlpha(alpha); - } - } - public float getTranslationX() { - if (AnimatorProxy.NEEDS_PROXY) { - return mProxy.getTranslationX(); - } else { - return super.getTranslationX(); - } - } - public void setTranslationX(float translationX) { - if (AnimatorProxy.NEEDS_PROXY) { - mProxy.setTranslationX(translationX); - } else { - super.setTranslationX(translationX); - } - } - public float getTranslationY() { - if (AnimatorProxy.NEEDS_PROXY) { - return mProxy.getTranslationY(); - } else { - return super.getTranslationY(); - } - } - public void setTranslationY(float translationY) { - if (AnimatorProxy.NEEDS_PROXY) { - mProxy.setTranslationY(translationY); - } else { - super.setTranslationY(translationY); - } - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/view/animation/AnimatorProxy.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/view/animation/AnimatorProxy.java deleted file mode 100644 index 067d0494e..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/view/animation/AnimatorProxy.java +++ /dev/null @@ -1,212 +0,0 @@ -package com.actionbarsherlock.internal.nineoldandroids.view.animation; - -import java.lang.ref.WeakReference; -import java.util.WeakHashMap; -import android.graphics.Matrix; -import android.graphics.RectF; -import android.os.Build; -import android.util.FloatMath; -import android.view.View; -import android.view.animation.Animation; -import android.view.animation.Transformation; - -public final class AnimatorProxy extends Animation { - public static final boolean NEEDS_PROXY = Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB; - - private static final WeakHashMap PROXIES = - new WeakHashMap(); - - public static AnimatorProxy wrap(View view) { - AnimatorProxy proxy = PROXIES.get(view); - if (proxy == null) { - proxy = new AnimatorProxy(view); - PROXIES.put(view, proxy); - } - return proxy; - } - - private final WeakReference mView; - - private float mAlpha = 1; - private float mScaleX = 1; - private float mScaleY = 1; - private float mTranslationX; - private float mTranslationY; - - private final RectF mBefore = new RectF(); - private final RectF mAfter = new RectF(); - private final Matrix mTempMatrix = new Matrix(); - - private AnimatorProxy(View view) { - setDuration(0); //perform transformation immediately - setFillAfter(true); //persist transformation beyond duration - view.setAnimation(this); - mView = new WeakReference(view); - } - - public float getAlpha() { - return mAlpha; - } - public void setAlpha(float alpha) { - if (mAlpha != alpha) { - mAlpha = alpha; - View view = mView.get(); - if (view != null) { - view.invalidate(); - } - } - } - public float getScaleX() { - return mScaleX; - } - public void setScaleX(float scaleX) { - if (mScaleX != scaleX) { - prepareForUpdate(); - mScaleX = scaleX; - invalidateAfterUpdate(); - } - } - public float getScaleY() { - return mScaleY; - } - public void setScaleY(float scaleY) { - if (mScaleY != scaleY) { - prepareForUpdate(); - mScaleY = scaleY; - invalidateAfterUpdate(); - } - } - public int getScrollX() { - View view = mView.get(); - if (view == null) { - return 0; - } - return view.getScrollX(); - } - public void setScrollX(int value) { - View view = mView.get(); - if (view != null) { - view.scrollTo(value, view.getScrollY()); - } - } - public int getScrollY() { - View view = mView.get(); - if (view == null) { - return 0; - } - return view.getScrollY(); - } - public void setScrollY(int value) { - View view = mView.get(); - if (view != null) { - view.scrollTo(view.getScrollY(), value); - } - } - - public float getTranslationX() { - return mTranslationX; - } - public void setTranslationX(float translationX) { - if (mTranslationX != translationX) { - prepareForUpdate(); - mTranslationX = translationX; - invalidateAfterUpdate(); - } - } - public float getTranslationY() { - return mTranslationY; - } - public void setTranslationY(float translationY) { - if (mTranslationY != translationY) { - prepareForUpdate(); - mTranslationY = translationY; - invalidateAfterUpdate(); - } - } - - private void prepareForUpdate() { - View view = mView.get(); - if (view != null) { - computeRect(mBefore, view); - } - } - private void invalidateAfterUpdate() { - View view = mView.get(); - if (view == null) { - return; - } - View parent = (View)view.getParent(); - if (parent == null) { - return; - } - - view.setAnimation(this); - - final RectF after = mAfter; - computeRect(after, view); - after.union(mBefore); - - parent.invalidate( - (int) FloatMath.floor(after.left), - (int) FloatMath.floor(after.top), - (int) FloatMath.ceil(after.right), - (int) FloatMath.ceil(after.bottom)); - } - - private void computeRect(final RectF r, View view) { - // compute current rectangle according to matrix transformation - final float w = view.getWidth(); - final float h = view.getHeight(); - - // use a rectangle at 0,0 to make sure we don't run into issues with scaling - r.set(0, 0, w, h); - - final Matrix m = mTempMatrix; - m.reset(); - transformMatrix(m, view); - mTempMatrix.mapRect(r); - - r.offset(view.getLeft(), view.getTop()); - - // Straighten coords if rotations flipped them - if (r.right < r.left) { - final float f = r.right; - r.right = r.left; - r.left = f; - } - if (r.bottom < r.top) { - final float f = r.top; - r.top = r.bottom; - r.bottom = f; - } - } - - private void transformMatrix(Matrix m, View view) { - final float w = view.getWidth(); - final float h = view.getHeight(); - - final float sX = mScaleX; - final float sY = mScaleY; - if ((sX != 1.0f) || (sY != 1.0f)) { - final float deltaSX = ((sX * w) - w) / 2f; - final float deltaSY = ((sY * h) - h) / 2f; - m.postScale(sX, sY); - m.postTranslate(-deltaSX, -deltaSY); - } - m.postTranslate(mTranslationX, mTranslationY); - } - - @Override - protected void applyTransformation(float interpolatedTime, Transformation t) { - View view = mView.get(); - if (view != null) { - t.setAlpha(mAlpha); - transformMatrix(t.getMatrix(), view); - } - } - - @Override - public void reset() { - /* Do nothing. */ - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/widget/NineFrameLayout.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/widget/NineFrameLayout.java deleted file mode 100644 index 2c428e907..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/widget/NineFrameLayout.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.actionbarsherlock.internal.nineoldandroids.widget; - -import android.content.Context; -import android.util.AttributeSet; -import android.widget.FrameLayout; - -import com.actionbarsherlock.internal.nineoldandroids.view.animation.AnimatorProxy; - -public class NineFrameLayout extends FrameLayout { - private final AnimatorProxy mProxy; - - public NineFrameLayout(Context context) { - super(context); - mProxy = AnimatorProxy.NEEDS_PROXY ? AnimatorProxy.wrap(this) : null; - } - public NineFrameLayout(Context context, AttributeSet attrs) { - super(context, attrs); - mProxy = AnimatorProxy.NEEDS_PROXY ? AnimatorProxy.wrap(this) : null; - } - public NineFrameLayout(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - mProxy = AnimatorProxy.NEEDS_PROXY ? AnimatorProxy.wrap(this) : null; - } - - @Override - public void setVisibility(int visibility) { - if (mProxy != null) { - if (visibility == GONE) { - clearAnimation(); - } else if (visibility == VISIBLE) { - setAnimation(mProxy); - } - } - super.setVisibility(visibility); - } - - public float getAlpha() { - if (AnimatorProxy.NEEDS_PROXY) { - return mProxy.getAlpha(); - } else { - return super.getAlpha(); - } - } - public void setAlpha(float alpha) { - if (AnimatorProxy.NEEDS_PROXY) { - mProxy.setAlpha(alpha); - } else { - super.setAlpha(alpha); - } - } - public float getTranslationY() { - if (AnimatorProxy.NEEDS_PROXY) { - return mProxy.getTranslationY(); - } else { - return super.getTranslationY(); - } - } - public void setTranslationY(float translationY) { - if (AnimatorProxy.NEEDS_PROXY) { - mProxy.setTranslationY(translationY); - } else { - super.setTranslationY(translationY); - } - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/widget/NineHorizontalScrollView.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/widget/NineHorizontalScrollView.java deleted file mode 100644 index 129b5aaaa..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/widget/NineHorizontalScrollView.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.actionbarsherlock.internal.nineoldandroids.widget; - -import android.content.Context; -import android.widget.HorizontalScrollView; -import com.actionbarsherlock.internal.nineoldandroids.view.animation.AnimatorProxy; - -public class NineHorizontalScrollView extends HorizontalScrollView { - private final AnimatorProxy mProxy; - - public NineHorizontalScrollView(Context context) { - super(context); - mProxy = AnimatorProxy.NEEDS_PROXY ? AnimatorProxy.wrap(this) : null; - } - - @Override - public void setVisibility(int visibility) { - if (mProxy != null) { - if (visibility == GONE) { - clearAnimation(); - } else if (visibility == VISIBLE) { - setAnimation(mProxy); - } - } - super.setVisibility(visibility); - } - - public float getAlpha() { - if (AnimatorProxy.NEEDS_PROXY) { - return mProxy.getAlpha(); - } else { - return super.getAlpha(); - } - } - public void setAlpha(float alpha) { - if (AnimatorProxy.NEEDS_PROXY) { - mProxy.setAlpha(alpha); - } else { - super.setAlpha(alpha); - } - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/widget/NineLinearLayout.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/widget/NineLinearLayout.java deleted file mode 100644 index a670b1f64..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/nineoldandroids/widget/NineLinearLayout.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.actionbarsherlock.internal.nineoldandroids.widget; - -import android.content.Context; -import android.util.AttributeSet; -import android.widget.LinearLayout; - -import com.actionbarsherlock.internal.nineoldandroids.view.animation.AnimatorProxy; - -public class NineLinearLayout extends LinearLayout { - private final AnimatorProxy mProxy; - - public NineLinearLayout(Context context) { - super(context); - mProxy = AnimatorProxy.NEEDS_PROXY ? AnimatorProxy.wrap(this) : null; - } - public NineLinearLayout(Context context, AttributeSet attrs) { - super(context, attrs); - mProxy = AnimatorProxy.NEEDS_PROXY ? AnimatorProxy.wrap(this) : null; - } - public NineLinearLayout(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - mProxy = AnimatorProxy.NEEDS_PROXY ? AnimatorProxy.wrap(this) : null; - } - - @Override - public void setVisibility(int visibility) { - if (mProxy != null) { - if (visibility == GONE) { - clearAnimation(); - } else if (visibility == VISIBLE) { - setAnimation(mProxy); - } - } - super.setVisibility(visibility); - } - - public float getAlpha() { - if (AnimatorProxy.NEEDS_PROXY) { - return mProxy.getAlpha(); - } else { - return super.getAlpha(); - } - } - public void setAlpha(float alpha) { - if (AnimatorProxy.NEEDS_PROXY) { - mProxy.setAlpha(alpha); - } else { - super.setAlpha(alpha); - } - } - public float getTranslationX() { - if (AnimatorProxy.NEEDS_PROXY) { - return mProxy.getTranslationX(); - } else { - return super.getTranslationX(); - } - } - public void setTranslationX(float translationX) { - if (AnimatorProxy.NEEDS_PROXY) { - mProxy.setTranslationX(translationX); - } else { - super.setTranslationX(translationX); - } - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/ActionProviderWrapper.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/ActionProviderWrapper.java deleted file mode 100644 index b136d50f0..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/ActionProviderWrapper.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.actionbarsherlock.internal.view; - -import com.actionbarsherlock.internal.view.menu.SubMenuWrapper; -import com.actionbarsherlock.view.ActionProvider; -import android.view.View; - -public class ActionProviderWrapper extends android.view.ActionProvider { - private final ActionProvider mProvider; - - - public ActionProviderWrapper(ActionProvider provider) { - super(null/*TODO*/); //XXX this *should* be unused - mProvider = provider; - } - - - public ActionProvider unwrap() { - return mProvider; - } - - @Override - public View onCreateActionView() { - return mProvider.onCreateActionView(); - } - - @Override - public boolean hasSubMenu() { - return mProvider.hasSubMenu(); - } - - @Override - public boolean onPerformDefaultAction() { - return mProvider.onPerformDefaultAction(); - } - - @Override - public void onPrepareSubMenu(android.view.SubMenu subMenu) { - mProvider.onPrepareSubMenu(new SubMenuWrapper(subMenu)); - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/StandaloneActionMode.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/StandaloneActionMode.java deleted file mode 100644 index 0a87bd3f7..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/StandaloneActionMode.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.actionbarsherlock.internal.view; - -import android.content.Context; -import android.view.View; -import android.view.accessibility.AccessibilityEvent; - -import java.lang.ref.WeakReference; - -import com.actionbarsherlock.internal.view.menu.MenuBuilder; -import com.actionbarsherlock.internal.view.menu.MenuPopupHelper; -import com.actionbarsherlock.internal.view.menu.SubMenuBuilder; -import com.actionbarsherlock.internal.widget.ActionBarContextView; -import com.actionbarsherlock.view.ActionMode; -import com.actionbarsherlock.view.Menu; -import com.actionbarsherlock.view.MenuInflater; -import com.actionbarsherlock.view.MenuItem; - -public class StandaloneActionMode extends ActionMode implements MenuBuilder.Callback { - private Context mContext; - private ActionBarContextView mContextView; - private ActionMode.Callback mCallback; - private WeakReference mCustomView; - private boolean mFinished; - private boolean mFocusable; - - private MenuBuilder mMenu; - - public StandaloneActionMode(Context context, ActionBarContextView view, - ActionMode.Callback callback, boolean isFocusable) { - mContext = context; - mContextView = view; - mCallback = callback; - - mMenu = new MenuBuilder(context).setDefaultShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); - mMenu.setCallback(this); - mFocusable = isFocusable; - } - - @Override - public void setTitle(CharSequence title) { - mContextView.setTitle(title); - } - - @Override - public void setSubtitle(CharSequence subtitle) { - mContextView.setSubtitle(subtitle); - } - - @Override - public void setTitle(int resId) { - setTitle(mContext.getString(resId)); - } - - @Override - public void setSubtitle(int resId) { - setSubtitle(mContext.getString(resId)); - } - - @Override - public void setCustomView(View view) { - mContextView.setCustomView(view); - mCustomView = view != null ? new WeakReference(view) : null; - } - - @Override - public void invalidate() { - mCallback.onPrepareActionMode(this, mMenu); - } - - @Override - public void finish() { - if (mFinished) { - return; - } - mFinished = true; - - mContextView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); - mCallback.onDestroyActionMode(this); - } - - @Override - public Menu getMenu() { - return mMenu; - } - - @Override - public CharSequence getTitle() { - return mContextView.getTitle(); - } - - @Override - public CharSequence getSubtitle() { - return mContextView.getSubtitle(); - } - - @Override - public View getCustomView() { - return mCustomView != null ? mCustomView.get() : null; - } - - @Override - public MenuInflater getMenuInflater() { - return new MenuInflater(mContext); - } - - public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) { - return mCallback.onActionItemClicked(this, item); - } - - public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) { - } - - public boolean onSubMenuSelected(SubMenuBuilder subMenu) { - if (!subMenu.hasVisibleItems()) { - return true; - } - - new MenuPopupHelper(mContext, subMenu).show(); - return true; - } - - public void onCloseSubMenu(SubMenuBuilder menu) { - } - - public void onMenuModeChange(MenuBuilder menu) { - invalidate(); - mContextView.showOverflowMenu(); - } - - public boolean isUiFocusable() { - return mFocusable; - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/View_HasStateListenerSupport.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/View_HasStateListenerSupport.java deleted file mode 100644 index 7d45e81be..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/View_HasStateListenerSupport.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.actionbarsherlock.internal.view; - -public interface View_HasStateListenerSupport { - void addOnAttachStateChangeListener(View_OnAttachStateChangeListener listener); - void removeOnAttachStateChangeListener(View_OnAttachStateChangeListener listener); -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/View_OnAttachStateChangeListener.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/View_OnAttachStateChangeListener.java deleted file mode 100644 index 3869d3290..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/View_OnAttachStateChangeListener.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.actionbarsherlock.internal.view; - -import android.view.View; - -public interface View_OnAttachStateChangeListener { - void onViewAttachedToWindow(View v); - void onViewDetachedFromWindow(View v); -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/ActionMenu.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/ActionMenu.java deleted file mode 100644 index 0354ad1ad..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/ActionMenu.java +++ /dev/null @@ -1,264 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.view.menu; - -import java.util.ArrayList; -import java.util.List; - -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.view.KeyEvent; - -import com.actionbarsherlock.view.Menu; -import com.actionbarsherlock.view.MenuItem; -import com.actionbarsherlock.view.SubMenu; - -/** - * @hide - */ -public class ActionMenu implements Menu { - private Context mContext; - - private boolean mIsQwerty; - - private ArrayList mItems; - - public ActionMenu(Context context) { - mContext = context; - mItems = new ArrayList(); - } - - public Context getContext() { - return mContext; - } - - public MenuItem add(CharSequence title) { - return add(0, 0, 0, title); - } - - public MenuItem add(int titleRes) { - return add(0, 0, 0, titleRes); - } - - public MenuItem add(int groupId, int itemId, int order, int titleRes) { - return add(groupId, itemId, order, mContext.getResources().getString(titleRes)); - } - - public MenuItem add(int groupId, int itemId, int order, CharSequence title) { - ActionMenuItem item = new ActionMenuItem(getContext(), - groupId, itemId, 0, order, title); - mItems.add(order, item); - return item; - } - - public int addIntentOptions(int groupId, int itemId, int order, - ComponentName caller, Intent[] specifics, Intent intent, int flags, - MenuItem[] outSpecificItems) { - PackageManager pm = mContext.getPackageManager(); - final List lri = - pm.queryIntentActivityOptions(caller, specifics, intent, 0); - final int N = lri != null ? lri.size() : 0; - - if ((flags & FLAG_APPEND_TO_GROUP) == 0) { - removeGroup(groupId); - } - - for (int i=0; i= 0) { - outSpecificItems[ri.specificIndex] = item; - } - } - - return N; - } - - public SubMenu addSubMenu(CharSequence title) { - // TODO Implement submenus - return null; - } - - public SubMenu addSubMenu(int titleRes) { - // TODO Implement submenus - return null; - } - - public SubMenu addSubMenu(int groupId, int itemId, int order, - CharSequence title) { - // TODO Implement submenus - return null; - } - - public SubMenu addSubMenu(int groupId, int itemId, int order, int titleRes) { - // TODO Implement submenus - return null; - } - - public void clear() { - mItems.clear(); - } - - public void close() { - } - - private int findItemIndex(int id) { - final ArrayList items = mItems; - final int itemCount = items.size(); - for (int i = 0; i < itemCount; i++) { - if (items.get(i).getItemId() == id) { - return i; - } - } - - return -1; - } - - public MenuItem findItem(int id) { - return mItems.get(findItemIndex(id)); - } - - public MenuItem getItem(int index) { - return mItems.get(index); - } - - public boolean hasVisibleItems() { - final ArrayList items = mItems; - final int itemCount = items.size(); - - for (int i = 0; i < itemCount; i++) { - if (items.get(i).isVisible()) { - return true; - } - } - - return false; - } - - private ActionMenuItem findItemWithShortcut(int keyCode, KeyEvent event) { - // TODO Make this smarter. - final boolean qwerty = mIsQwerty; - final ArrayList items = mItems; - final int itemCount = items.size(); - - for (int i = 0; i < itemCount; i++) { - ActionMenuItem item = items.get(i); - final char shortcut = qwerty ? item.getAlphabeticShortcut() : - item.getNumericShortcut(); - if (keyCode == shortcut) { - return item; - } - } - return null; - } - - public boolean isShortcutKey(int keyCode, KeyEvent event) { - return findItemWithShortcut(keyCode, event) != null; - } - - public boolean performIdentifierAction(int id, int flags) { - final int index = findItemIndex(id); - if (index < 0) { - return false; - } - - return mItems.get(index).invoke(); - } - - public boolean performShortcut(int keyCode, KeyEvent event, int flags) { - ActionMenuItem item = findItemWithShortcut(keyCode, event); - if (item == null) { - return false; - } - - return item.invoke(); - } - - public void removeGroup(int groupId) { - final ArrayList items = mItems; - int itemCount = items.size(); - int i = 0; - while (i < itemCount) { - if (items.get(i).getGroupId() == groupId) { - items.remove(i); - itemCount--; - } else { - i++; - } - } - } - - public void removeItem(int id) { - mItems.remove(findItemIndex(id)); - } - - public void setGroupCheckable(int group, boolean checkable, - boolean exclusive) { - final ArrayList items = mItems; - final int itemCount = items.size(); - - for (int i = 0; i < itemCount; i++) { - ActionMenuItem item = items.get(i); - if (item.getGroupId() == group) { - item.setCheckable(checkable); - item.setExclusiveCheckable(exclusive); - } - } - } - - public void setGroupEnabled(int group, boolean enabled) { - final ArrayList items = mItems; - final int itemCount = items.size(); - - for (int i = 0; i < itemCount; i++) { - ActionMenuItem item = items.get(i); - if (item.getGroupId() == group) { - item.setEnabled(enabled); - } - } - } - - public void setGroupVisible(int group, boolean visible) { - final ArrayList items = mItems; - final int itemCount = items.size(); - - for (int i = 0; i < itemCount; i++) { - ActionMenuItem item = items.get(i); - if (item.getGroupId() == group) { - item.setVisible(visible); - } - } - } - - public void setQwertyMode(boolean isQwerty) { - mIsQwerty = isQwerty; - } - - public int size() { - return mItems.size(); - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/ActionMenuItem.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/ActionMenuItem.java deleted file mode 100644 index 510b97488..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/ActionMenuItem.java +++ /dev/null @@ -1,278 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.view.menu; - -import android.content.Context; -import android.content.Intent; -import android.graphics.drawable.Drawable; -import android.view.ContextMenu.ContextMenuInfo; -import android.view.View; - -import com.actionbarsherlock.view.ActionProvider; -import com.actionbarsherlock.view.MenuItem; -import com.actionbarsherlock.view.SubMenu; - -/** - * @hide - */ -public class ActionMenuItem implements MenuItem { - private final int mId; - private final int mGroup; - //UNUSED private final int mCategoryOrder; - private final int mOrdering; - - private CharSequence mTitle; - private CharSequence mTitleCondensed; - private Intent mIntent; - private char mShortcutNumericChar; - private char mShortcutAlphabeticChar; - - private Drawable mIconDrawable; - //UNUSED private int mIconResId = NO_ICON; - - private Context mContext; - - private MenuItem.OnMenuItemClickListener mClickListener; - - //UNUSED private static final int NO_ICON = 0; - - private int mFlags = ENABLED; - private static final int CHECKABLE = 0x00000001; - private static final int CHECKED = 0x00000002; - private static final int EXCLUSIVE = 0x00000004; - private static final int HIDDEN = 0x00000008; - private static final int ENABLED = 0x00000010; - - public ActionMenuItem(Context context, int group, int id, int categoryOrder, int ordering, - CharSequence title) { - mContext = context; - mId = id; - mGroup = group; - //UNUSED mCategoryOrder = categoryOrder; - mOrdering = ordering; - mTitle = title; - } - - public char getAlphabeticShortcut() { - return mShortcutAlphabeticChar; - } - - public int getGroupId() { - return mGroup; - } - - public Drawable getIcon() { - return mIconDrawable; - } - - public Intent getIntent() { - return mIntent; - } - - public int getItemId() { - return mId; - } - - public ContextMenuInfo getMenuInfo() { - return null; - } - - public char getNumericShortcut() { - return mShortcutNumericChar; - } - - public int getOrder() { - return mOrdering; - } - - public SubMenu getSubMenu() { - return null; - } - - public CharSequence getTitle() { - return mTitle; - } - - public CharSequence getTitleCondensed() { - return mTitleCondensed; - } - - public boolean hasSubMenu() { - return false; - } - - public boolean isCheckable() { - return (mFlags & CHECKABLE) != 0; - } - - public boolean isChecked() { - return (mFlags & CHECKED) != 0; - } - - public boolean isEnabled() { - return (mFlags & ENABLED) != 0; - } - - public boolean isVisible() { - return (mFlags & HIDDEN) == 0; - } - - public MenuItem setAlphabeticShortcut(char alphaChar) { - mShortcutAlphabeticChar = alphaChar; - return this; - } - - public MenuItem setCheckable(boolean checkable) { - mFlags = (mFlags & ~CHECKABLE) | (checkable ? CHECKABLE : 0); - return this; - } - - public ActionMenuItem setExclusiveCheckable(boolean exclusive) { - mFlags = (mFlags & ~EXCLUSIVE) | (exclusive ? EXCLUSIVE : 0); - return this; - } - - public MenuItem setChecked(boolean checked) { - mFlags = (mFlags & ~CHECKED) | (checked ? CHECKED : 0); - return this; - } - - public MenuItem setEnabled(boolean enabled) { - mFlags = (mFlags & ~ENABLED) | (enabled ? ENABLED : 0); - return this; - } - - public MenuItem setIcon(Drawable icon) { - mIconDrawable = icon; - //UNUSED mIconResId = NO_ICON; - return this; - } - - public MenuItem setIcon(int iconRes) { - //UNUSED mIconResId = iconRes; - mIconDrawable = mContext.getResources().getDrawable(iconRes); - return this; - } - - public MenuItem setIntent(Intent intent) { - mIntent = intent; - return this; - } - - public MenuItem setNumericShortcut(char numericChar) { - mShortcutNumericChar = numericChar; - return this; - } - - public MenuItem setOnMenuItemClickListener(OnMenuItemClickListener menuItemClickListener) { - mClickListener = menuItemClickListener; - return this; - } - - public MenuItem setShortcut(char numericChar, char alphaChar) { - mShortcutNumericChar = numericChar; - mShortcutAlphabeticChar = alphaChar; - return this; - } - - public MenuItem setTitle(CharSequence title) { - mTitle = title; - return this; - } - - public MenuItem setTitle(int title) { - mTitle = mContext.getResources().getString(title); - return this; - } - - public MenuItem setTitleCondensed(CharSequence title) { - mTitleCondensed = title; - return this; - } - - public MenuItem setVisible(boolean visible) { - mFlags = (mFlags & HIDDEN) | (visible ? 0 : HIDDEN); - return this; - } - - public boolean invoke() { - if (mClickListener != null && mClickListener.onMenuItemClick(this)) { - return true; - } - - if (mIntent != null) { - mContext.startActivity(mIntent); - return true; - } - - return false; - } - - public void setShowAsAction(int show) { - // Do nothing. ActionMenuItems always show as action buttons. - } - - public MenuItem setActionView(View actionView) { - throw new UnsupportedOperationException(); - } - - public View getActionView() { - return null; - } - - @Override - public MenuItem setActionView(int resId) { - throw new UnsupportedOperationException(); - } - - @Override - public ActionProvider getActionProvider() { - return null; - } - - @Override - public MenuItem setActionProvider(ActionProvider actionProvider) { - throw new UnsupportedOperationException(); - } - - @Override - public MenuItem setShowAsActionFlags(int actionEnum) { - setShowAsAction(actionEnum); - return this; - } - - @Override - public boolean expandActionView() { - return false; - } - - @Override - public boolean collapseActionView() { - return false; - } - - @Override - public boolean isActionViewExpanded() { - return false; - } - - @Override - public MenuItem setOnActionExpandListener(OnActionExpandListener listener) { - // No need to save the listener; ActionMenuItem does not support collapsing items. - return this; - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/ActionMenuItemView.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/ActionMenuItemView.java deleted file mode 100644 index dcb50f362..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/ActionMenuItemView.java +++ /dev/null @@ -1,295 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.view.menu; - -import java.util.HashSet; -import java.util.Set; -import android.content.Context; -import android.content.res.TypedArray; -import android.graphics.Rect; -import android.graphics.drawable.Drawable; -import android.os.Build; -import android.text.TextUtils; -import android.util.AttributeSet; -import android.view.Gravity; -import android.view.MotionEvent; -import android.view.View; -import android.view.accessibility.AccessibilityEvent; -import android.widget.ImageButton; -import android.widget.LinearLayout; -import android.widget.Toast; - -import com.actionbarsherlock.R; -import com.actionbarsherlock.internal.view.View_HasStateListenerSupport; -import com.actionbarsherlock.internal.view.View_OnAttachStateChangeListener; -import com.actionbarsherlock.internal.widget.CapitalizingButton; - -import static com.actionbarsherlock.internal.ResourcesCompat.getResources_getBoolean; - -/** - * @hide - */ -public class ActionMenuItemView extends LinearLayout - implements MenuView.ItemView, View.OnClickListener, View.OnLongClickListener, - ActionMenuView.ActionMenuChildView, View_HasStateListenerSupport { - //UNUSED private static final String TAG = "ActionMenuItemView"; - - private MenuItemImpl mItemData; - private CharSequence mTitle; - private MenuBuilder.ItemInvoker mItemInvoker; - - private ImageButton mImageButton; - private CapitalizingButton mTextButton; - private boolean mAllowTextWithIcon; - private boolean mExpandedFormat; - private int mMinWidth; - - private final Set mListeners = new HashSet(); - - public ActionMenuItemView(Context context) { - this(context, null); - } - - public ActionMenuItemView(Context context, AttributeSet attrs) { - this(context, attrs, 0); - } - - public ActionMenuItemView(Context context, AttributeSet attrs, int defStyle) { - //TODO super(context, attrs, defStyle); - super(context, attrs); - mAllowTextWithIcon = getResources_getBoolean(context, - R.bool.abs__config_allowActionMenuItemTextWithIcon); - TypedArray a = context.obtainStyledAttributes(attrs, - R.styleable.SherlockActionMenuItemView, 0, 0); - mMinWidth = a.getDimensionPixelSize( - R.styleable.SherlockActionMenuItemView_android_minWidth, 0); - a.recycle(); - } - - @Override - public void addOnAttachStateChangeListener(View_OnAttachStateChangeListener listener) { - mListeners.add(listener); - } - - @Override - public void removeOnAttachStateChangeListener(View_OnAttachStateChangeListener listener) { - mListeners.remove(listener); - } - - @Override - protected void onAttachedToWindow() { - super.onAttachedToWindow(); - for (View_OnAttachStateChangeListener listener : mListeners) { - listener.onViewAttachedToWindow(this); - } - } - - @Override - protected void onDetachedFromWindow() { - super.onDetachedFromWindow(); - for (View_OnAttachStateChangeListener listener : mListeners) { - listener.onViewDetachedFromWindow(this); - } - } - - @Override - public void onFinishInflate() { - - mImageButton = (ImageButton) findViewById(R.id.abs__imageButton); - mTextButton = (CapitalizingButton) findViewById(R.id.abs__textButton); - mImageButton.setOnClickListener(this); - mTextButton.setOnClickListener(this); - mImageButton.setOnLongClickListener(this); - setOnClickListener(this); - setOnLongClickListener(this); - } - - public MenuItemImpl getItemData() { - return mItemData; - } - - public void initialize(MenuItemImpl itemData, int menuType) { - mItemData = itemData; - - setIcon(itemData.getIcon()); - setTitle(itemData.getTitleForItemView(this)); // Title only takes effect if there is no icon - setId(itemData.getItemId()); - - setVisibility(itemData.isVisible() ? View.VISIBLE : View.GONE); - setEnabled(itemData.isEnabled()); - } - - @Override - public void setEnabled(boolean enabled) { - super.setEnabled(enabled); - mImageButton.setEnabled(enabled); - mTextButton.setEnabled(enabled); - } - - public void onClick(View v) { - if (mItemInvoker != null) { - mItemInvoker.invokeItem(mItemData); - } - } - - public void setItemInvoker(MenuBuilder.ItemInvoker invoker) { - mItemInvoker = invoker; - } - - public boolean prefersCondensedTitle() { - return true; - } - - public void setCheckable(boolean checkable) { - // TODO Support checkable action items - } - - public void setChecked(boolean checked) { - // TODO Support checkable action items - } - - public void setExpandedFormat(boolean expandedFormat) { - if (mExpandedFormat != expandedFormat) { - mExpandedFormat = expandedFormat; - if (mItemData != null) { - mItemData.actionFormatChanged(); - } - } - } - - private void updateTextButtonVisibility() { - boolean visible = !TextUtils.isEmpty(mTextButton.getText()); - visible &= mImageButton.getDrawable() == null || - (mItemData.showsTextAsAction() && (mAllowTextWithIcon || mExpandedFormat)); - - mTextButton.setVisibility(visible ? VISIBLE : GONE); - } - - public void setIcon(Drawable icon) { - mImageButton.setImageDrawable(icon); - if (icon != null) { - mImageButton.setVisibility(VISIBLE); - } else { - mImageButton.setVisibility(GONE); - } - - updateTextButtonVisibility(); - } - - public boolean hasText() { - return mTextButton.getVisibility() != GONE; - } - - public void setShortcut(boolean showShortcut, char shortcutKey) { - // Action buttons don't show text for shortcut keys. - } - - public void setTitle(CharSequence title) { - mTitle = title; - - mTextButton.setTextCompat(mTitle); - - setContentDescription(mTitle); - updateTextButtonVisibility(); - } - - @Override - public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { - onPopulateAccessibilityEvent(event); - return true; - } - - @Override - public void onPopulateAccessibilityEvent(AccessibilityEvent event) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { - super.onPopulateAccessibilityEvent(event); - } - final CharSequence cdesc = getContentDescription(); - if (!TextUtils.isEmpty(cdesc)) { - event.getText().add(cdesc); - } - } - - @Override - public boolean dispatchHoverEvent(MotionEvent event) { - // Don't allow children to hover; we want this to be treated as a single component. - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { - return onHoverEvent(event); - } - return false; - } - - public boolean showsIcon() { - return true; - } - - public boolean needsDividerBefore() { - return hasText() && mItemData.getIcon() == null; - } - - public boolean needsDividerAfter() { - return hasText(); - } - - @Override - public boolean onLongClick(View v) { - if (hasText()) { - // Don't show the cheat sheet for items that already show text. - return false; - } - - final int[] screenPos = new int[2]; - final Rect displayFrame = new Rect(); - getLocationOnScreen(screenPos); - getWindowVisibleDisplayFrame(displayFrame); - - final Context context = getContext(); - final int width = getWidth(); - final int height = getHeight(); - final int midy = screenPos[1] + height / 2; - final int screenWidth = context.getResources().getDisplayMetrics().widthPixels; - - Toast cheatSheet = Toast.makeText(context, mItemData.getTitle(), Toast.LENGTH_SHORT); - if (midy < displayFrame.height()) { - // Show along the top; follow action buttons - cheatSheet.setGravity(Gravity.TOP | Gravity.RIGHT, - screenWidth - screenPos[0] - width / 2, height); - } else { - // Show along the bottom center - cheatSheet.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, height); - } - cheatSheet.show(); - return true; - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - - final int widthMode = MeasureSpec.getMode(widthMeasureSpec); - final int specSize = MeasureSpec.getSize(widthMeasureSpec); - final int oldMeasuredWidth = getMeasuredWidth(); - final int targetWidth = widthMode == MeasureSpec.AT_MOST ? Math.min(specSize, mMinWidth) - : mMinWidth; - - if (widthMode != MeasureSpec.EXACTLY && mMinWidth > 0 && oldMeasuredWidth < targetWidth) { - // Remeasure at exactly the minimum width. - super.onMeasure(MeasureSpec.makeMeasureSpec(targetWidth, MeasureSpec.EXACTLY), - heightMeasureSpec); - } - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/ActionMenuPresenter.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/ActionMenuPresenter.java deleted file mode 100644 index 6f568c698..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/ActionMenuPresenter.java +++ /dev/null @@ -1,721 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.view.menu; - -import static com.actionbarsherlock.internal.ResourcesCompat.getResources_getInteger; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Set; -import android.content.Context; -import android.content.res.Configuration; -import android.content.res.Resources; -import android.content.res.TypedArray; -import android.os.Build; -import android.os.Parcel; -import android.os.Parcelable; -import android.util.SparseBooleanArray; -import android.view.SoundEffectConstants; -import android.view.View; -import android.view.View.MeasureSpec; -import android.view.ViewConfiguration; -import android.view.ViewGroup; -import android.widget.ImageButton; -import com.actionbarsherlock.R; -import com.actionbarsherlock.internal.view.View_HasStateListenerSupport; -import com.actionbarsherlock.internal.view.View_OnAttachStateChangeListener; -import com.actionbarsherlock.internal.view.menu.ActionMenuView.ActionMenuChildView; -import com.actionbarsherlock.view.ActionProvider; -import com.actionbarsherlock.view.MenuItem; - -/** - * MenuPresenter for building action menus as seen in the action bar and action modes. - */ -public class ActionMenuPresenter extends BaseMenuPresenter - implements ActionProvider.SubUiVisibilityListener { - //UNUSED private static final String TAG = "ActionMenuPresenter"; - - private View mOverflowButton; - private boolean mReserveOverflow; - private boolean mReserveOverflowSet; - private int mWidthLimit; - private int mActionItemWidthLimit; - private int mMaxItems; - private boolean mMaxItemsSet; - private boolean mStrictWidthLimit; - private boolean mWidthLimitSet; - private boolean mExpandedActionViewsExclusive; - - private int mMinCellSize; - - // Group IDs that have been added as actions - used temporarily, allocated here for reuse. - private final SparseBooleanArray mActionButtonGroups = new SparseBooleanArray(); - - private View mScrapActionButtonView; - - private OverflowPopup mOverflowPopup; - private ActionButtonSubmenu mActionButtonPopup; - - private OpenOverflowRunnable mPostedOpenRunnable; - - final PopupPresenterCallback mPopupPresenterCallback = new PopupPresenterCallback(); - int mOpenSubMenuId; - - public ActionMenuPresenter(Context context) { - super(context, R.layout.abs__action_menu_layout, - R.layout.abs__action_menu_item_layout); - } - - @Override - public void initForMenu(Context context, MenuBuilder menu) { - super.initForMenu(context, menu); - - final Resources res = context.getResources(); - - if (!mReserveOverflowSet) { - mReserveOverflow = reserveOverflow(mContext); - } - - if (!mWidthLimitSet) { - mWidthLimit = res.getDisplayMetrics().widthPixels / 2; - } - - // Measure for initial configuration - if (!mMaxItemsSet) { - mMaxItems = getResources_getInteger(context, R.integer.abs__max_action_buttons); - } - - int width = mWidthLimit; - if (mReserveOverflow) { - if (mOverflowButton == null) { - mOverflowButton = new OverflowMenuButton(mSystemContext); - final int spec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); - mOverflowButton.measure(spec, spec); - } - width -= mOverflowButton.getMeasuredWidth(); - } else { - mOverflowButton = null; - } - - mActionItemWidthLimit = width; - - mMinCellSize = (int) (ActionMenuView.MIN_CELL_SIZE * res.getDisplayMetrics().density); - - // Drop a scrap view as it may no longer reflect the proper context/config. - mScrapActionButtonView = null; - } - - public static boolean reserveOverflow(Context context) { - //Check for theme-forced overflow action item - TypedArray a = context.getTheme().obtainStyledAttributes(R.styleable.SherlockTheme); - boolean result = a.getBoolean(R.styleable.SherlockTheme_absForceOverflow, false); - a.recycle(); - if (result) { - return true; - } - - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH) { - return (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB); - } else { - return !HasPermanentMenuKey.get(context); - } - } - - private static class HasPermanentMenuKey { - public static boolean get(Context context) { - return ViewConfiguration.get(context).hasPermanentMenuKey(); - } - } - - public void onConfigurationChanged(Configuration newConfig) { - if (!mMaxItemsSet) { - mMaxItems = getResources_getInteger(mContext, - R.integer.abs__max_action_buttons); - if (mMenu != null) { - mMenu.onItemsChanged(true); - } - } - } - - public void setWidthLimit(int width, boolean strict) { - mWidthLimit = width; - mStrictWidthLimit = strict; - mWidthLimitSet = true; - } - - public void setReserveOverflow(boolean reserveOverflow) { - mReserveOverflow = reserveOverflow; - mReserveOverflowSet = true; - } - - public void setItemLimit(int itemCount) { - mMaxItems = itemCount; - mMaxItemsSet = true; - } - - public void setExpandedActionViewsExclusive(boolean isExclusive) { - mExpandedActionViewsExclusive = isExclusive; - } - - @Override - public MenuView getMenuView(ViewGroup root) { - MenuView result = super.getMenuView(root); - ((ActionMenuView) result).setPresenter(this); - return result; - } - - @Override - public View getItemView(MenuItemImpl item, View convertView, ViewGroup parent) { - View actionView = item.getActionView(); - if (actionView == null || item.hasCollapsibleActionView()) { - if (!(convertView instanceof ActionMenuItemView)) { - convertView = null; - } - actionView = super.getItemView(item, convertView, parent); - } - actionView.setVisibility(item.isActionViewExpanded() ? View.GONE : View.VISIBLE); - - final ActionMenuView menuParent = (ActionMenuView) parent; - final ViewGroup.LayoutParams lp = actionView.getLayoutParams(); - if (!menuParent.checkLayoutParams(lp)) { - actionView.setLayoutParams(menuParent.generateLayoutParams(lp)); - } - return actionView; - } - - @Override - public void bindItemView(MenuItemImpl item, MenuView.ItemView itemView) { - itemView.initialize(item, 0); - - final ActionMenuView menuView = (ActionMenuView) mMenuView; - ActionMenuItemView actionItemView = (ActionMenuItemView) itemView; - actionItemView.setItemInvoker(menuView); - } - - @Override - public boolean shouldIncludeItem(int childIndex, MenuItemImpl item) { - return item.isActionButton(); - } - - @Override - public void updateMenuView(boolean cleared) { - super.updateMenuView(cleared); - - if (mMenu != null) { - final ArrayList actionItems = mMenu.getActionItems(); - final int count = actionItems.size(); - for (int i = 0; i < count; i++) { - final ActionProvider provider = actionItems.get(i).getActionProvider(); - if (provider != null) { - provider.setSubUiVisibilityListener(this); - } - } - } - - final ArrayList nonActionItems = mMenu != null ? - mMenu.getNonActionItems() : null; - - boolean hasOverflow = false; - if (mReserveOverflow && nonActionItems != null) { - final int count = nonActionItems.size(); - if (count == 1) { - hasOverflow = !nonActionItems.get(0).isActionViewExpanded(); - } else { - hasOverflow = count > 0; - } - } - - if (hasOverflow) { - if (mOverflowButton == null) { - mOverflowButton = new OverflowMenuButton(mSystemContext); - } - ViewGroup parent = (ViewGroup) mOverflowButton.getParent(); - if (parent != mMenuView) { - if (parent != null) { - parent.removeView(mOverflowButton); - } - ActionMenuView menuView = (ActionMenuView) mMenuView; - menuView.addView(mOverflowButton, menuView.generateOverflowButtonLayoutParams()); - } - } else if (mOverflowButton != null && mOverflowButton.getParent() == mMenuView) { - ((ViewGroup) mMenuView).removeView(mOverflowButton); - } - - ((ActionMenuView) mMenuView).setOverflowReserved(mReserveOverflow); - } - - @Override - public boolean filterLeftoverView(ViewGroup parent, int childIndex) { - if (parent.getChildAt(childIndex) == mOverflowButton) return false; - return super.filterLeftoverView(parent, childIndex); - } - - public boolean onSubMenuSelected(SubMenuBuilder subMenu) { - if (!subMenu.hasVisibleItems()) return false; - - SubMenuBuilder topSubMenu = subMenu; - while (topSubMenu.getParentMenu() != mMenu) { - topSubMenu = (SubMenuBuilder) topSubMenu.getParentMenu(); - } - View anchor = findViewForItem(topSubMenu.getItem()); - if (anchor == null) { - if (mOverflowButton == null) return false; - anchor = mOverflowButton; - } - - mOpenSubMenuId = subMenu.getItem().getItemId(); - mActionButtonPopup = new ActionButtonSubmenu(mContext, subMenu); - mActionButtonPopup.setAnchorView(anchor); - mActionButtonPopup.show(); - super.onSubMenuSelected(subMenu); - return true; - } - - private View findViewForItem(MenuItem item) { - final ViewGroup parent = (ViewGroup) mMenuView; - if (parent == null) return null; - - final int count = parent.getChildCount(); - for (int i = 0; i < count; i++) { - final View child = parent.getChildAt(i); - if (child instanceof MenuView.ItemView && - ((MenuView.ItemView) child).getItemData() == item) { - return child; - } - } - return null; - } - - /** - * Display the overflow menu if one is present. - * @return true if the overflow menu was shown, false otherwise. - */ - public boolean showOverflowMenu() { - if (mReserveOverflow && !isOverflowMenuShowing() && mMenu != null && mMenuView != null && - mPostedOpenRunnable == null && !mMenu.getNonActionItems().isEmpty()) { - OverflowPopup popup = new OverflowPopup(mContext, mMenu, mOverflowButton, true); - mPostedOpenRunnable = new OpenOverflowRunnable(popup); - // Post this for later; we might still need a layout for the anchor to be right. - ((View) mMenuView).post(mPostedOpenRunnable); - - // ActionMenuPresenter uses null as a callback argument here - // to indicate overflow is opening. - super.onSubMenuSelected(null); - - return true; - } - return false; - } - - /** - * Hide the overflow menu if it is currently showing. - * - * @return true if the overflow menu was hidden, false otherwise. - */ - public boolean hideOverflowMenu() { - if (mPostedOpenRunnable != null && mMenuView != null) { - ((View) mMenuView).removeCallbacks(mPostedOpenRunnable); - mPostedOpenRunnable = null; - return true; - } - - MenuPopupHelper popup = mOverflowPopup; - if (popup != null) { - popup.dismiss(); - return true; - } - return false; - } - - /** - * Dismiss all popup menus - overflow and submenus. - * @return true if popups were dismissed, false otherwise. (This can be because none were open.) - */ - public boolean dismissPopupMenus() { - boolean result = hideOverflowMenu(); - result |= hideSubMenus(); - return result; - } - - /** - * Dismiss all submenu popups. - * - * @return true if popups were dismissed, false otherwise. (This can be because none were open.) - */ - public boolean hideSubMenus() { - if (mActionButtonPopup != null) { - mActionButtonPopup.dismiss(); - return true; - } - return false; - } - - /** - * @return true if the overflow menu is currently showing - */ - public boolean isOverflowMenuShowing() { - return mOverflowPopup != null && mOverflowPopup.isShowing(); - } - - /** - * @return true if space has been reserved in the action menu for an overflow item. - */ - public boolean isOverflowReserved() { - return mReserveOverflow; - } - - public boolean flagActionItems() { - final ArrayList visibleItems = mMenu.getVisibleItems(); - final int itemsSize = visibleItems.size(); - int maxActions = mMaxItems; - int widthLimit = mActionItemWidthLimit; - final int querySpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); - final ViewGroup parent = (ViewGroup) mMenuView; - - int requiredItems = 0; - int requestedItems = 0; - int firstActionWidth = 0; - boolean hasOverflow = false; - for (int i = 0; i < itemsSize; i++) { - MenuItemImpl item = visibleItems.get(i); - if (item.requiresActionButton()) { - requiredItems++; - } else if (item.requestsActionButton()) { - requestedItems++; - } else { - hasOverflow = true; - } - if (mExpandedActionViewsExclusive && item.isActionViewExpanded()) { - // Overflow everything if we have an expanded action view and we're - // space constrained. - maxActions = 0; - } - } - - // Reserve a spot for the overflow item if needed. - if (mReserveOverflow && - (hasOverflow || requiredItems + requestedItems > maxActions)) { - maxActions--; - } - maxActions -= requiredItems; - - final SparseBooleanArray seenGroups = mActionButtonGroups; - seenGroups.clear(); - - int cellSize = 0; - int cellsRemaining = 0; - if (mStrictWidthLimit) { - cellsRemaining = widthLimit / mMinCellSize; - final int cellSizeRemaining = widthLimit % mMinCellSize; - cellSize = mMinCellSize + cellSizeRemaining / cellsRemaining; - } - - // Flag as many more requested items as will fit. - for (int i = 0; i < itemsSize; i++) { - MenuItemImpl item = visibleItems.get(i); - - if (item.requiresActionButton()) { - View v = getItemView(item, mScrapActionButtonView, parent); - if (mScrapActionButtonView == null) { - mScrapActionButtonView = v; - } - if (mStrictWidthLimit) { - cellsRemaining -= ActionMenuView.measureChildForCells(v, - cellSize, cellsRemaining, querySpec, 0); - } else { - v.measure(querySpec, querySpec); - } - final int measuredWidth = v.getMeasuredWidth(); - widthLimit -= measuredWidth; - if (firstActionWidth == 0) { - firstActionWidth = measuredWidth; - } - final int groupId = item.getGroupId(); - if (groupId != 0) { - seenGroups.put(groupId, true); - } - item.setIsActionButton(true); - } else if (item.requestsActionButton()) { - // Items in a group with other items that already have an action slot - // can break the max actions rule, but not the width limit. - final int groupId = item.getGroupId(); - final boolean inGroup = seenGroups.get(groupId); - boolean isAction = (maxActions > 0 || inGroup) && widthLimit > 0 && - (!mStrictWidthLimit || cellsRemaining > 0); - - if (isAction) { - View v = getItemView(item, mScrapActionButtonView, parent); - if (mScrapActionButtonView == null) { - mScrapActionButtonView = v; - } - if (mStrictWidthLimit) { - final int cells = ActionMenuView.measureChildForCells(v, - cellSize, cellsRemaining, querySpec, 0); - cellsRemaining -= cells; - if (cells == 0) { - isAction = false; - } - } else { - v.measure(querySpec, querySpec); - } - final int measuredWidth = v.getMeasuredWidth(); - widthLimit -= measuredWidth; - if (firstActionWidth == 0) { - firstActionWidth = measuredWidth; - } - - if (mStrictWidthLimit) { - isAction &= widthLimit >= 0; - } else { - // Did this push the entire first item past the limit? - isAction &= widthLimit + firstActionWidth > 0; - } - } - - if (isAction && groupId != 0) { - seenGroups.put(groupId, true); - } else if (inGroup) { - // We broke the width limit. Demote the whole group, they all overflow now. - seenGroups.put(groupId, false); - for (int j = 0; j < i; j++) { - MenuItemImpl areYouMyGroupie = visibleItems.get(j); - if (areYouMyGroupie.getGroupId() == groupId) { - // Give back the action slot - if (areYouMyGroupie.isActionButton()) maxActions++; - areYouMyGroupie.setIsActionButton(false); - } - } - } - - if (isAction) maxActions--; - - item.setIsActionButton(isAction); - } - } - return true; - } - - @Override - public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) { - dismissPopupMenus(); - super.onCloseMenu(menu, allMenusAreClosing); - } - - @Override - public Parcelable onSaveInstanceState() { - SavedState state = new SavedState(); - state.openSubMenuId = mOpenSubMenuId; - return state; - } - - @Override - public void onRestoreInstanceState(Parcelable state) { - SavedState saved = (SavedState) state; - if (saved.openSubMenuId > 0) { - MenuItem item = mMenu.findItem(saved.openSubMenuId); - if (item != null) { - SubMenuBuilder subMenu = (SubMenuBuilder) item.getSubMenu(); - onSubMenuSelected(subMenu); - } - } - } - - @Override - public void onSubUiVisibilityChanged(boolean isVisible) { - if (isVisible) { - // Not a submenu, but treat it like one. - super.onSubMenuSelected(null); - } else { - mMenu.close(false); - } - } - - private static class SavedState implements Parcelable { - public int openSubMenuId; - - SavedState() { - } - - SavedState(Parcel in) { - openSubMenuId = in.readInt(); - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(openSubMenuId); - } - - @SuppressWarnings("unused") - public static final Parcelable.Creator CREATOR - = new Parcelable.Creator() { - public SavedState createFromParcel(Parcel in) { - return new SavedState(in); - } - - public SavedState[] newArray(int size) { - return new SavedState[size]; - } - }; - } - - private class OverflowMenuButton extends ImageButton implements ActionMenuChildView, View_HasStateListenerSupport { - private final Set mListeners = new HashSet(); - - public OverflowMenuButton(Context context) { - super(context, null, R.attr.actionOverflowButtonStyle); - - setClickable(true); - setFocusable(true); - setVisibility(VISIBLE); - setEnabled(true); - } - - @Override - public boolean performClick() { - if (super.performClick()) { - return true; - } - - playSoundEffect(SoundEffectConstants.CLICK); - showOverflowMenu(); - return true; - } - - public boolean needsDividerBefore() { - return false; - } - - public boolean needsDividerAfter() { - return false; - } - - @Override - protected void onAttachedToWindow() { - super.onAttachedToWindow(); - for (View_OnAttachStateChangeListener listener : mListeners) { - listener.onViewAttachedToWindow(this); - } - } - - @Override - protected void onDetachedFromWindow() { - super.onDetachedFromWindow(); - for (View_OnAttachStateChangeListener listener : mListeners) { - listener.onViewDetachedFromWindow(this); - } - } - - @Override - public void addOnAttachStateChangeListener(View_OnAttachStateChangeListener listener) { - mListeners.add(listener); - } - - @Override - public void removeOnAttachStateChangeListener(View_OnAttachStateChangeListener listener) { - mListeners.remove(listener); - } - } - - private class OverflowPopup extends MenuPopupHelper { - public OverflowPopup(Context context, MenuBuilder menu, View anchorView, - boolean overflowOnly) { - super(context, menu, anchorView, overflowOnly); - setCallback(mPopupPresenterCallback); - } - - @Override - public void onDismiss() { - super.onDismiss(); - mMenu.close(); - mOverflowPopup = null; - } - } - - private class ActionButtonSubmenu extends MenuPopupHelper { - //UNUSED private SubMenuBuilder mSubMenu; - - public ActionButtonSubmenu(Context context, SubMenuBuilder subMenu) { - super(context, subMenu); - //UNUSED mSubMenu = subMenu; - - MenuItemImpl item = (MenuItemImpl) subMenu.getItem(); - if (!item.isActionButton()) { - // Give a reasonable anchor to nested submenus. - setAnchorView(mOverflowButton == null ? (View) mMenuView : mOverflowButton); - } - - setCallback(mPopupPresenterCallback); - - boolean preserveIconSpacing = false; - final int count = subMenu.size(); - for (int i = 0; i < count; i++) { - MenuItem childItem = subMenu.getItem(i); - if (childItem.isVisible() && childItem.getIcon() != null) { - preserveIconSpacing = true; - break; - } - } - setForceShowIcon(preserveIconSpacing); - } - - @Override - public void onDismiss() { - super.onDismiss(); - mActionButtonPopup = null; - mOpenSubMenuId = 0; - } - } - - private class PopupPresenterCallback implements MenuPresenter.Callback { - - @Override - public boolean onOpenSubMenu(MenuBuilder subMenu) { - if (subMenu == null) return false; - - mOpenSubMenuId = ((SubMenuBuilder) subMenu).getItem().getItemId(); - return false; - } - - @Override - public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) { - if (menu instanceof SubMenuBuilder) { - ((SubMenuBuilder) menu).getRootMenu().close(false); - } - } - } - - private class OpenOverflowRunnable implements Runnable { - private OverflowPopup mPopup; - - public OpenOverflowRunnable(OverflowPopup popup) { - mPopup = popup; - } - - public void run() { - mMenu.changeMenuMode(); - final View menuView = (View) mMenuView; - if (menuView != null && menuView.getWindowToken() != null && mPopup.tryShow()) { - mOverflowPopup = mPopup; - } - mPostedOpenRunnable = null; - } - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/ActionMenuView.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/ActionMenuView.java deleted file mode 100644 index e090677a1..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/ActionMenuView.java +++ /dev/null @@ -1,572 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.actionbarsherlock.internal.view.menu; - -import android.content.Context; -import android.content.res.Configuration; -import android.graphics.Canvas; -import android.os.Build; -import android.util.AttributeSet; -import android.view.Gravity; -import android.view.View; -import android.view.ViewGroup; -import android.view.accessibility.AccessibilityEvent; -import android.widget.LinearLayout; -import com.actionbarsherlock.internal.widget.IcsLinearLayout; - -/** - * @hide - */ -public class ActionMenuView extends IcsLinearLayout implements MenuBuilder.ItemInvoker, MenuView { - //UNUSED private static final String TAG = "ActionMenuView"; - private static final boolean IS_FROYO = Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO; - - static final int MIN_CELL_SIZE = 56; // dips - static final int GENERATED_ITEM_PADDING = 4; // dips - - private MenuBuilder mMenu; - - private boolean mReserveOverflow; - private ActionMenuPresenter mPresenter; - private boolean mFormatItems; - private int mFormatItemsWidth; - private int mMinCellSize; - private int mGeneratedItemPadding; - //UNUSED private int mMeasuredExtraWidth; - - private boolean mFirst = true; - - public ActionMenuView(Context context) { - this(context, null); - } - - public ActionMenuView(Context context, AttributeSet attrs) { - super(context, attrs); - setBaselineAligned(false); - final float density = context.getResources().getDisplayMetrics().density; - mMinCellSize = (int) (MIN_CELL_SIZE * density); - mGeneratedItemPadding = (int) (GENERATED_ITEM_PADDING * density); - } - - public void setPresenter(ActionMenuPresenter presenter) { - mPresenter = presenter; - } - - public boolean isExpandedFormat() { - return mFormatItems; - } - - @Override - public void onConfigurationChanged(Configuration newConfig) { - if (IS_FROYO) { - super.onConfigurationChanged(newConfig); - } - mPresenter.updateMenuView(false); - - if (mPresenter != null && mPresenter.isOverflowMenuShowing()) { - mPresenter.hideOverflowMenu(); - mPresenter.showOverflowMenu(); - } - } - - @Override - protected void onDraw(Canvas canvas) { - //Need to trigger a relayout since we may have been added extremely - //late in the initial rendering (e.g., when contained in a ViewPager). - //See: https://github.com/JakeWharton/ActionBarSherlock/issues/272 - if (!IS_FROYO && mFirst) { - mFirst = false; - requestLayout(); - return; - } - super.onDraw(canvas); - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - // If we've been given an exact size to match, apply special formatting during layout. - final boolean wasFormatted = mFormatItems; - mFormatItems = MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY; - - if (wasFormatted != mFormatItems) { - mFormatItemsWidth = 0; // Reset this when switching modes - } - - // Special formatting can change whether items can fit as action buttons. - // Kick the menu and update presenters when this changes. - final int widthSize = MeasureSpec.getMode(widthMeasureSpec); - if (mFormatItems && mMenu != null && widthSize != mFormatItemsWidth) { - mFormatItemsWidth = widthSize; - mMenu.onItemsChanged(true); - } - - if (mFormatItems) { - onMeasureExactFormat(widthMeasureSpec, heightMeasureSpec); - } else { - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - } - } - - private void onMeasureExactFormat(int widthMeasureSpec, int heightMeasureSpec) { - // We already know the width mode is EXACTLY if we're here. - final int heightMode = MeasureSpec.getMode(heightMeasureSpec); - int widthSize = MeasureSpec.getSize(widthMeasureSpec); - int heightSize = MeasureSpec.getSize(heightMeasureSpec); - - final int widthPadding = getPaddingLeft() + getPaddingRight(); - final int heightPadding = getPaddingTop() + getPaddingBottom(); - - widthSize -= widthPadding; - - // Divide the view into cells. - final int cellCount = widthSize / mMinCellSize; - final int cellSizeRemaining = widthSize % mMinCellSize; - - if (cellCount == 0) { - // Give up, nothing fits. - setMeasuredDimension(widthSize, 0); - return; - } - - final int cellSize = mMinCellSize + cellSizeRemaining / cellCount; - - int cellsRemaining = cellCount; - int maxChildHeight = 0; - int maxCellsUsed = 0; - int expandableItemCount = 0; - int visibleItemCount = 0; - boolean hasOverflow = false; - - // This is used as a bitfield to locate the smallest items present. Assumes childCount < 64. - long smallestItemsAt = 0; - - final int childCount = getChildCount(); - for (int i = 0; i < childCount; i++) { - final View child = getChildAt(i); - if (child.getVisibility() == GONE) continue; - - final boolean isGeneratedItem = child instanceof ActionMenuItemView; - visibleItemCount++; - - if (isGeneratedItem) { - // Reset padding for generated menu item views; it may change below - // and views are recycled. - child.setPadding(mGeneratedItemPadding, 0, mGeneratedItemPadding, 0); - } - - final LayoutParams lp = (LayoutParams) child.getLayoutParams(); - lp.expanded = false; - lp.extraPixels = 0; - lp.cellsUsed = 0; - lp.expandable = false; - lp.leftMargin = 0; - lp.rightMargin = 0; - lp.preventEdgeOffset = isGeneratedItem && ((ActionMenuItemView) child).hasText(); - - // Overflow always gets 1 cell. No more, no less. - final int cellsAvailable = lp.isOverflowButton ? 1 : cellsRemaining; - - final int cellsUsed = measureChildForCells(child, cellSize, cellsAvailable, - heightMeasureSpec, heightPadding); - - maxCellsUsed = Math.max(maxCellsUsed, cellsUsed); - if (lp.expandable) expandableItemCount++; - if (lp.isOverflowButton) hasOverflow = true; - - cellsRemaining -= cellsUsed; - maxChildHeight = Math.max(maxChildHeight, child.getMeasuredHeight()); - if (cellsUsed == 1) smallestItemsAt |= (1 << i); - } - - // When we have overflow and a single expanded (text) item, we want to try centering it - // visually in the available space even though overflow consumes some of it. - final boolean centerSingleExpandedItem = hasOverflow && visibleItemCount == 2; - - // Divide space for remaining cells if we have items that can expand. - // Try distributing whole leftover cells to smaller items first. - - boolean needsExpansion = false; - while (expandableItemCount > 0 && cellsRemaining > 0) { - int minCells = Integer.MAX_VALUE; - long minCellsAt = 0; // Bit locations are indices of relevant child views - int minCellsItemCount = 0; - for (int i = 0; i < childCount; i++) { - final View child = getChildAt(i); - final LayoutParams lp = (LayoutParams) child.getLayoutParams(); - - // Don't try to expand items that shouldn't. - if (!lp.expandable) continue; - - // Mark indices of children that can receive an extra cell. - if (lp.cellsUsed < minCells) { - minCells = lp.cellsUsed; - minCellsAt = 1 << i; - minCellsItemCount = 1; - } else if (lp.cellsUsed == minCells) { - minCellsAt |= 1 << i; - minCellsItemCount++; - } - } - - // Items that get expanded will always be in the set of smallest items when we're done. - smallestItemsAt |= minCellsAt; - - if (minCellsItemCount > cellsRemaining) break; // Couldn't expand anything evenly. Stop. - - // We have enough cells, all minimum size items will be incremented. - minCells++; - - for (int i = 0; i < childCount; i++) { - final View child = getChildAt(i); - final LayoutParams lp = (LayoutParams) child.getLayoutParams(); - if ((minCellsAt & (1 << i)) == 0) { - // If this item is already at our small item count, mark it for later. - if (lp.cellsUsed == minCells) smallestItemsAt |= 1 << i; - continue; - } - - if (centerSingleExpandedItem && lp.preventEdgeOffset && cellsRemaining == 1) { - // Add padding to this item such that it centers. - child.setPadding(mGeneratedItemPadding + cellSize, 0, mGeneratedItemPadding, 0); - } - lp.cellsUsed++; - lp.expanded = true; - cellsRemaining--; - } - - needsExpansion = true; - } - - // Divide any space left that wouldn't divide along cell boundaries - // evenly among the smallest items - - final boolean singleItem = !hasOverflow && visibleItemCount == 1; - if (cellsRemaining > 0 && smallestItemsAt != 0 && - (cellsRemaining < visibleItemCount - 1 || singleItem || maxCellsUsed > 1)) { - float expandCount = Long.bitCount(smallestItemsAt); - - if (!singleItem) { - // The items at the far edges may only expand by half in order to pin to either side. - if ((smallestItemsAt & 1) != 0) { - LayoutParams lp = (LayoutParams) getChildAt(0).getLayoutParams(); - if (!lp.preventEdgeOffset) expandCount -= 0.5f; - } - if ((smallestItemsAt & (1 << (childCount - 1))) != 0) { - LayoutParams lp = ((LayoutParams) getChildAt(childCount - 1).getLayoutParams()); - if (!lp.preventEdgeOffset) expandCount -= 0.5f; - } - } - - final int extraPixels = expandCount > 0 ? - (int) (cellsRemaining * cellSize / expandCount) : 0; - - for (int i = 0; i < childCount; i++) { - if ((smallestItemsAt & (1 << i)) == 0) continue; - - final View child = getChildAt(i); - final LayoutParams lp = (LayoutParams) child.getLayoutParams(); - if (child instanceof ActionMenuItemView) { - // If this is one of our views, expand and measure at the larger size. - lp.extraPixels = extraPixels; - lp.expanded = true; - if (i == 0 && !lp.preventEdgeOffset) { - // First item gets part of its new padding pushed out of sight. - // The last item will get this implicitly from layout. - lp.leftMargin = -extraPixels / 2; - } - needsExpansion = true; - } else if (lp.isOverflowButton) { - lp.extraPixels = extraPixels; - lp.expanded = true; - lp.rightMargin = -extraPixels / 2; - needsExpansion = true; - } else { - // If we don't know what it is, give it some margins instead - // and let it center within its space. We still want to pin - // against the edges. - if (i != 0) { - lp.leftMargin = extraPixels / 2; - } - if (i != childCount - 1) { - lp.rightMargin = extraPixels / 2; - } - } - } - - cellsRemaining = 0; - } - - // Remeasure any items that have had extra space allocated to them. - if (needsExpansion) { - int heightSpec = MeasureSpec.makeMeasureSpec(heightSize - heightPadding, heightMode); - for (int i = 0; i < childCount; i++) { - final View child = getChildAt(i); - final LayoutParams lp = (LayoutParams) child.getLayoutParams(); - - if (!lp.expanded) continue; - - final int width = lp.cellsUsed * cellSize + lp.extraPixels; - child.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), heightSpec); - } - } - - if (heightMode != MeasureSpec.EXACTLY) { - heightSize = maxChildHeight; - } - - setMeasuredDimension(widthSize, heightSize); - //UNUSED mMeasuredExtraWidth = cellsRemaining * cellSize; - } - - /** - * Measure a child view to fit within cell-based formatting. The child's width - * will be measured to a whole multiple of cellSize. - * - *

Sets the expandable and cellsUsed fields of LayoutParams. - * - * @param child Child to measure - * @param cellSize Size of one cell - * @param cellsRemaining Number of cells remaining that this view can expand to fill - * @param parentHeightMeasureSpec MeasureSpec used by the parent view - * @param parentHeightPadding Padding present in the parent view - * @return Number of cells this child was measured to occupy - */ - static int measureChildForCells(View child, int cellSize, int cellsRemaining, - int parentHeightMeasureSpec, int parentHeightPadding) { - final LayoutParams lp = (LayoutParams) child.getLayoutParams(); - - final int childHeightSize = MeasureSpec.getSize(parentHeightMeasureSpec) - - parentHeightPadding; - final int childHeightMode = MeasureSpec.getMode(parentHeightMeasureSpec); - final int childHeightSpec = MeasureSpec.makeMeasureSpec(childHeightSize, childHeightMode); - - int cellsUsed = 0; - if (cellsRemaining > 0) { - final int childWidthSpec = MeasureSpec.makeMeasureSpec( - cellSize * cellsRemaining, MeasureSpec.AT_MOST); - child.measure(childWidthSpec, childHeightSpec); - - final int measuredWidth = child.getMeasuredWidth(); - cellsUsed = measuredWidth / cellSize; - if (measuredWidth % cellSize != 0) cellsUsed++; - } - - final ActionMenuItemView itemView = child instanceof ActionMenuItemView ? - (ActionMenuItemView) child : null; - final boolean expandable = !lp.isOverflowButton && itemView != null && itemView.hasText(); - lp.expandable = expandable; - - lp.cellsUsed = cellsUsed; - final int targetWidth = cellsUsed * cellSize; - child.measure(MeasureSpec.makeMeasureSpec(targetWidth, MeasureSpec.EXACTLY), - childHeightSpec); - return cellsUsed; - } - - @Override - protected void onLayout(boolean changed, int left, int top, int right, int bottom) { - if (!mFormatItems) { - super.onLayout(changed, left, top, right, bottom); - return; - } - - final int childCount = getChildCount(); - final int midVertical = (top + bottom) / 2; - final int dividerWidth = 0;//getDividerWidth(); - int overflowWidth = 0; - //UNUSED int nonOverflowWidth = 0; - int nonOverflowCount = 0; - int widthRemaining = right - left - getPaddingRight() - getPaddingLeft(); - boolean hasOverflow = false; - for (int i = 0; i < childCount; i++) { - final View v = getChildAt(i); - if (v.getVisibility() == GONE) { - continue; - } - - LayoutParams p = (LayoutParams) v.getLayoutParams(); - if (p.isOverflowButton) { - overflowWidth = v.getMeasuredWidth(); - if (hasDividerBeforeChildAt(i)) { - overflowWidth += dividerWidth; - } - - int height = v.getMeasuredHeight(); - int r = getWidth() - getPaddingRight() - p.rightMargin; - int l = r - overflowWidth; - int t = midVertical - (height / 2); - int b = t + height; - v.layout(l, t, r, b); - - widthRemaining -= overflowWidth; - hasOverflow = true; - } else { - final int size = v.getMeasuredWidth() + p.leftMargin + p.rightMargin; - //UNUSED nonOverflowWidth += size; - widthRemaining -= size; - //if (hasDividerBeforeChildAt(i)) { - //UNUSED nonOverflowWidth += dividerWidth; - //} - nonOverflowCount++; - } - } - - if (childCount == 1 && !hasOverflow) { - // Center a single child - final View v = getChildAt(0); - final int width = v.getMeasuredWidth(); - final int height = v.getMeasuredHeight(); - final int midHorizontal = (right - left) / 2; - final int l = midHorizontal - width / 2; - final int t = midVertical - height / 2; - v.layout(l, t, l + width, t + height); - return; - } - - final int spacerCount = nonOverflowCount - (hasOverflow ? 0 : 1); - final int spacerSize = Math.max(0, spacerCount > 0 ? widthRemaining / spacerCount : 0); - - int startLeft = getPaddingLeft(); - for (int i = 0; i < childCount; i++) { - final View v = getChildAt(i); - final LayoutParams lp = (LayoutParams) v.getLayoutParams(); - if (v.getVisibility() == GONE || lp.isOverflowButton) { - continue; - } - - startLeft += lp.leftMargin; - int width = v.getMeasuredWidth(); - int height = v.getMeasuredHeight(); - int t = midVertical - height / 2; - v.layout(startLeft, t, startLeft + width, t + height); - startLeft += width + lp.rightMargin + spacerSize; - } - } - - @Override - public void onDetachedFromWindow() { - super.onDetachedFromWindow(); - mPresenter.dismissPopupMenus(); - } - - public boolean isOverflowReserved() { - return mReserveOverflow; - } - - public void setOverflowReserved(boolean reserveOverflow) { - mReserveOverflow = reserveOverflow; - } - - @Override - protected LayoutParams generateDefaultLayoutParams() { - LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, - LayoutParams.WRAP_CONTENT); - params.gravity = Gravity.CENTER_VERTICAL; - return params; - } - - @Override - public LayoutParams generateLayoutParams(AttributeSet attrs) { - return new LayoutParams(getContext(), attrs); - } - - @Override - protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) { - if (p instanceof LayoutParams) { - LayoutParams result = new LayoutParams((LayoutParams) p); - if (result.gravity <= Gravity.NO_GRAVITY) { - result.gravity = Gravity.CENTER_VERTICAL; - } - return result; - } - return generateDefaultLayoutParams(); - } - - @Override - protected boolean checkLayoutParams(ViewGroup.LayoutParams p) { - return p != null && p instanceof LayoutParams; - } - - public LayoutParams generateOverflowButtonLayoutParams() { - LayoutParams result = generateDefaultLayoutParams(); - result.isOverflowButton = true; - return result; - } - - public boolean invokeItem(MenuItemImpl item) { - return mMenu.performItemAction(item, 0); - } - - public int getWindowAnimations() { - return 0; - } - - public void initialize(MenuBuilder menu) { - mMenu = menu; - } - - //@Override - protected boolean hasDividerBeforeChildAt(int childIndex) { - final View childBefore = getChildAt(childIndex - 1); - final View child = getChildAt(childIndex); - boolean result = false; - if (childIndex < getChildCount() && childBefore instanceof ActionMenuChildView) { - result |= ((ActionMenuChildView) childBefore).needsDividerAfter(); - } - if (childIndex > 0 && child instanceof ActionMenuChildView) { - result |= ((ActionMenuChildView) child).needsDividerBefore(); - } - return result; - } - - public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { - return false; - } - - public interface ActionMenuChildView { - public boolean needsDividerBefore(); - public boolean needsDividerAfter(); - } - - public static class LayoutParams extends LinearLayout.LayoutParams { - public boolean isOverflowButton; - public int cellsUsed; - public int extraPixels; - public boolean expandable; - public boolean preventEdgeOffset; - - public boolean expanded; - - public LayoutParams(Context c, AttributeSet attrs) { - super(c, attrs); - } - - public LayoutParams(LayoutParams other) { - super((LinearLayout.LayoutParams) other); - isOverflowButton = other.isOverflowButton; - } - - public LayoutParams(int width, int height) { - super(width, height); - isOverflowButton = false; - } - - public LayoutParams(int width, int height, boolean isOverflowButton) { - super(width, height); - this.isOverflowButton = isOverflowButton; - } - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/BaseMenuPresenter.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/BaseMenuPresenter.java deleted file mode 100644 index 6da26f2ae..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/BaseMenuPresenter.java +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.view.menu; - -import java.util.ArrayList; -import android.content.Context; -import android.os.Build; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -/** - * Base class for MenuPresenters that have a consistent container view and item - * views. Behaves similarly to an AdapterView in that existing item views will - * be reused if possible when items change. - */ -public abstract class BaseMenuPresenter implements MenuPresenter { - private static final boolean IS_HONEYCOMB = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB; - - protected Context mSystemContext; - protected Context mContext; - protected MenuBuilder mMenu; - protected LayoutInflater mSystemInflater; - protected LayoutInflater mInflater; - private Callback mCallback; - - private int mMenuLayoutRes; - private int mItemLayoutRes; - - protected MenuView mMenuView; - - private int mId; - - /** - * Construct a new BaseMenuPresenter. - * - * @param context Context for generating system-supplied views - * @param menuLayoutRes Layout resource ID for the menu container view - * @param itemLayoutRes Layout resource ID for a single item view - */ - public BaseMenuPresenter(Context context, int menuLayoutRes, int itemLayoutRes) { - mSystemContext = context; - mSystemInflater = LayoutInflater.from(context); - mMenuLayoutRes = menuLayoutRes; - mItemLayoutRes = itemLayoutRes; - } - - @Override - public void initForMenu(Context context, MenuBuilder menu) { - mContext = context; - mInflater = LayoutInflater.from(mContext); - mMenu = menu; - } - - @Override - public MenuView getMenuView(ViewGroup root) { - if (mMenuView == null) { - mMenuView = (MenuView) mSystemInflater.inflate(mMenuLayoutRes, root, false); - mMenuView.initialize(mMenu); - updateMenuView(true); - } - - return mMenuView; - } - - /** - * Reuses item views when it can - */ - public void updateMenuView(boolean cleared) { - final ViewGroup parent = (ViewGroup) mMenuView; - if (parent == null) return; - - int childIndex = 0; - if (mMenu != null) { - mMenu.flagActionItems(); - ArrayList visibleItems = mMenu.getVisibleItems(); - final int itemCount = visibleItems.size(); - for (int i = 0; i < itemCount; i++) { - MenuItemImpl item = visibleItems.get(i); - if (shouldIncludeItem(childIndex, item)) { - final View convertView = parent.getChildAt(childIndex); - final MenuItemImpl oldItem = convertView instanceof MenuView.ItemView ? - ((MenuView.ItemView) convertView).getItemData() : null; - final View itemView = getItemView(item, convertView, parent); - if (item != oldItem) { - // Don't let old states linger with new data. - itemView.setPressed(false); - if (IS_HONEYCOMB) itemView.jumpDrawablesToCurrentState(); - } - if (itemView != convertView) { - addItemView(itemView, childIndex); - } - childIndex++; - } - } - } - - // Remove leftover views. - while (childIndex < parent.getChildCount()) { - if (!filterLeftoverView(parent, childIndex)) { - childIndex++; - } - } - } - - /** - * Add an item view at the given index. - * - * @param itemView View to add - * @param childIndex Index within the parent to insert at - */ - protected void addItemView(View itemView, int childIndex) { - final ViewGroup currentParent = (ViewGroup) itemView.getParent(); - if (currentParent != null) { - currentParent.removeView(itemView); - } - ((ViewGroup) mMenuView).addView(itemView, childIndex); - } - - /** - * Filter the child view at index and remove it if appropriate. - * @param parent Parent to filter from - * @param childIndex Index to filter - * @return true if the child view at index was removed - */ - protected boolean filterLeftoverView(ViewGroup parent, int childIndex) { - parent.removeViewAt(childIndex); - return true; - } - - public void setCallback(Callback cb) { - mCallback = cb; - } - - /** - * Create a new item view that can be re-bound to other item data later. - * - * @return The new item view - */ - public MenuView.ItemView createItemView(ViewGroup parent) { - return (MenuView.ItemView) mSystemInflater.inflate(mItemLayoutRes, parent, false); - } - - /** - * Prepare an item view for use. See AdapterView for the basic idea at work here. - * This may require creating a new item view, but well-behaved implementations will - * re-use the view passed as convertView if present. The returned view will be populated - * with data from the item parameter. - * - * @param item Item to present - * @param convertView Existing view to reuse - * @param parent Intended parent view - use for inflation. - * @return View that presents the requested menu item - */ - public View getItemView(MenuItemImpl item, View convertView, ViewGroup parent) { - MenuView.ItemView itemView; - if (convertView instanceof MenuView.ItemView) { - itemView = (MenuView.ItemView) convertView; - } else { - itemView = createItemView(parent); - } - bindItemView(item, itemView); - return (View) itemView; - } - - /** - * Bind item data to an existing item view. - * - * @param item Item to bind - * @param itemView View to populate with item data - */ - public abstract void bindItemView(MenuItemImpl item, MenuView.ItemView itemView); - - /** - * Filter item by child index and item data. - * - * @param childIndex Indended presentation index of this item - * @param item Item to present - * @return true if this item should be included in this menu presentation; false otherwise - */ - public boolean shouldIncludeItem(int childIndex, MenuItemImpl item) { - return true; - } - - public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) { - if (mCallback != null) { - mCallback.onCloseMenu(menu, allMenusAreClosing); - } - } - - public boolean onSubMenuSelected(SubMenuBuilder menu) { - if (mCallback != null) { - return mCallback.onOpenSubMenu(menu); - } - return false; - } - - public boolean flagActionItems() { - return false; - } - - public boolean expandItemActionView(MenuBuilder menu, MenuItemImpl item) { - return false; - } - - public boolean collapseItemActionView(MenuBuilder menu, MenuItemImpl item) { - return false; - } - - public int getId() { - return mId; - } - - public void setId(int id) { - mId = id; - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/ListMenuItemView.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/ListMenuItemView.java deleted file mode 100644 index ac25c3736..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/ListMenuItemView.java +++ /dev/null @@ -1,278 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.view.menu; - -import com.actionbarsherlock.R; - -import android.content.Context; -import android.content.res.TypedArray; -import android.graphics.drawable.Drawable; -import android.util.AttributeSet; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.CheckBox; -import android.widget.CompoundButton; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.RadioButton; -import android.widget.TextView; - -/** - * The item view for each item in the ListView-based MenuViews. - */ -public class ListMenuItemView extends LinearLayout implements MenuView.ItemView { - private MenuItemImpl mItemData; - - private ImageView mIconView; - private RadioButton mRadioButton; - private TextView mTitleView; - private CheckBox mCheckBox; - private TextView mShortcutView; - - private Drawable mBackground; - private int mTextAppearance; - private Context mTextAppearanceContext; - private boolean mPreserveIconSpacing; - - //UNUSED private int mMenuType; - - private LayoutInflater mInflater; - - private boolean mForceShowIcon; - - final Context mContext; - - public ListMenuItemView(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs); - mContext = context; - - TypedArray a = - context.obtainStyledAttributes( - attrs, R.styleable.SherlockMenuView, defStyle, 0); - - mBackground = a.getDrawable(R.styleable.SherlockMenuView_itemBackground); - mTextAppearance = a.getResourceId(R.styleable. - SherlockMenuView_itemTextAppearance, -1); - mPreserveIconSpacing = a.getBoolean( - R.styleable.SherlockMenuView_preserveIconSpacing, false); - mTextAppearanceContext = context; - - a.recycle(); - } - - public ListMenuItemView(Context context, AttributeSet attrs) { - this(context, attrs, 0); - } - - @Override - protected void onFinishInflate() { - super.onFinishInflate(); - - setBackgroundDrawable(mBackground); - - mTitleView = (TextView) findViewById(R.id.abs__title); - if (mTextAppearance != -1) { - mTitleView.setTextAppearance(mTextAppearanceContext, - mTextAppearance); - } - - mShortcutView = (TextView) findViewById(R.id.abs__shortcut); - } - - public void initialize(MenuItemImpl itemData, int menuType) { - mItemData = itemData; - //UNUSED mMenuType = menuType; - - setVisibility(itemData.isVisible() ? View.VISIBLE : View.GONE); - - setTitle(itemData.getTitleForItemView(this)); - setCheckable(itemData.isCheckable()); - setShortcut(itemData.shouldShowShortcut(), itemData.getShortcut()); - setIcon(itemData.getIcon()); - setEnabled(itemData.isEnabled()); - } - - public void setForceShowIcon(boolean forceShow) { - mPreserveIconSpacing = mForceShowIcon = forceShow; - } - - public void setTitle(CharSequence title) { - if (title != null) { - mTitleView.setText(title); - - if (mTitleView.getVisibility() != VISIBLE) mTitleView.setVisibility(VISIBLE); - } else { - if (mTitleView.getVisibility() != GONE) mTitleView.setVisibility(GONE); - } - } - - public MenuItemImpl getItemData() { - return mItemData; - } - - public void setCheckable(boolean checkable) { - - if (!checkable && mRadioButton == null && mCheckBox == null) { - return; - } - - if (mRadioButton == null) { - insertRadioButton(); - } - if (mCheckBox == null) { - insertCheckBox(); - } - - // Depending on whether its exclusive check or not, the checkbox or - // radio button will be the one in use (and the other will be otherCompoundButton) - final CompoundButton compoundButton; - final CompoundButton otherCompoundButton; - - if (mItemData.isExclusiveCheckable()) { - compoundButton = mRadioButton; - otherCompoundButton = mCheckBox; - } else { - compoundButton = mCheckBox; - otherCompoundButton = mRadioButton; - } - - if (checkable) { - compoundButton.setChecked(mItemData.isChecked()); - - final int newVisibility = checkable ? VISIBLE : GONE; - if (compoundButton.getVisibility() != newVisibility) { - compoundButton.setVisibility(newVisibility); - } - - // Make sure the other compound button isn't visible - if (otherCompoundButton.getVisibility() != GONE) { - otherCompoundButton.setVisibility(GONE); - } - } else { - mCheckBox.setVisibility(GONE); - mRadioButton.setVisibility(GONE); - } - } - - public void setChecked(boolean checked) { - CompoundButton compoundButton; - - if (mItemData.isExclusiveCheckable()) { - if (mRadioButton == null) { - insertRadioButton(); - } - compoundButton = mRadioButton; - } else { - if (mCheckBox == null) { - insertCheckBox(); - } - compoundButton = mCheckBox; - } - - compoundButton.setChecked(checked); - } - - public void setShortcut(boolean showShortcut, char shortcutKey) { - final int newVisibility = (showShortcut && mItemData.shouldShowShortcut()) - ? VISIBLE : GONE; - - if (newVisibility == VISIBLE) { - mShortcutView.setText(mItemData.getShortcutLabel()); - } - - if (mShortcutView.getVisibility() != newVisibility) { - mShortcutView.setVisibility(newVisibility); - } - } - - public void setIcon(Drawable icon) { - final boolean showIcon = mItemData.shouldShowIcon() || mForceShowIcon; - if (!showIcon && !mPreserveIconSpacing) { - return; - } - - if (mIconView == null && icon == null && !mPreserveIconSpacing) { - return; - } - - if (mIconView == null) { - insertIconView(); - } - - if (icon != null || mPreserveIconSpacing) { - mIconView.setImageDrawable(showIcon ? icon : null); - - if (mIconView.getVisibility() != VISIBLE) { - mIconView.setVisibility(VISIBLE); - } - } else { - mIconView.setVisibility(GONE); - } - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - if (mIconView != null && mPreserveIconSpacing) { - // Enforce minimum icon spacing - ViewGroup.LayoutParams lp = getLayoutParams(); - LayoutParams iconLp = (LayoutParams) mIconView.getLayoutParams(); - if (lp.height > 0 && iconLp.width <= 0) { - iconLp.width = lp.height; - } - } - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - } - - private void insertIconView() { - LayoutInflater inflater = getInflater(); - mIconView = (ImageView) inflater.inflate(R.layout.abs__list_menu_item_icon, - this, false); - addView(mIconView, 0); - } - - private void insertRadioButton() { - LayoutInflater inflater = getInflater(); - mRadioButton = - (RadioButton) inflater.inflate(R.layout.abs__list_menu_item_radio, - this, false); - addView(mRadioButton); - } - - private void insertCheckBox() { - LayoutInflater inflater = getInflater(); - mCheckBox = - (CheckBox) inflater.inflate(R.layout.abs__list_menu_item_checkbox, - this, false); - addView(mCheckBox); - } - - public boolean prefersCondensedTitle() { - return false; - } - - public boolean showsIcon() { - return mForceShowIcon; - } - - private LayoutInflater getInflater() { - if (mInflater == null) { - mInflater = LayoutInflater.from(mContext); - } - return mInflater; - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/MenuBuilder.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/MenuBuilder.java deleted file mode 100644 index 179b8f037..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/MenuBuilder.java +++ /dev/null @@ -1,1335 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.view.menu; - - -import java.lang.ref.WeakReference; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; - -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.content.res.Configuration; -import android.content.res.Resources; -import android.graphics.drawable.Drawable; -import android.os.Bundle; -import android.os.Parcelable; -import android.util.SparseArray; -import android.view.ContextMenu.ContextMenuInfo; -import android.view.KeyCharacterMap; -import android.view.KeyEvent; -import android.view.View; - -import com.actionbarsherlock.R; -import com.actionbarsherlock.view.ActionProvider; -import com.actionbarsherlock.view.Menu; -import com.actionbarsherlock.view.MenuItem; -import com.actionbarsherlock.view.SubMenu; - -/** - * Implementation of the {@link android.view.Menu} interface for creating a - * standard menu UI. - */ -public class MenuBuilder implements Menu { - //UNUSED private static final String TAG = "MenuBuilder"; - - private static final String PRESENTER_KEY = "android:menu:presenters"; - private static final String ACTION_VIEW_STATES_KEY = "android:menu:actionviewstates"; - private static final String EXPANDED_ACTION_VIEW_ID = "android:menu:expandedactionview"; - - private static final int[] sCategoryToOrder = new int[] { - 1, /* No category */ - 4, /* CONTAINER */ - 5, /* SYSTEM */ - 3, /* SECONDARY */ - 2, /* ALTERNATIVE */ - 0, /* SELECTED_ALTERNATIVE */ - }; - - private final Context mContext; - private final Resources mResources; - - /** - * Whether the shortcuts should be qwerty-accessible. Use isQwertyMode() - * instead of accessing this directly. - */ - private boolean mQwertyMode; - - /** - * Whether the shortcuts should be visible on menus. Use isShortcutsVisible() - * instead of accessing this directly. - */ - private boolean mShortcutsVisible; - - /** - * Callback that will receive the various menu-related events generated by - * this class. Use getCallback to get a reference to the callback. - */ - private Callback mCallback; - - /** Contains all of the items for this menu */ - private ArrayList mItems; - - /** Contains only the items that are currently visible. This will be created/refreshed from - * {@link #getVisibleItems()} */ - private ArrayList mVisibleItems; - /** - * Whether or not the items (or any one item's shown state) has changed since it was last - * fetched from {@link #getVisibleItems()} - */ - private boolean mIsVisibleItemsStale; - - /** - * Contains only the items that should appear in the Action Bar, if present. - */ - private ArrayList mActionItems; - /** - * Contains items that should NOT appear in the Action Bar, if present. - */ - private ArrayList mNonActionItems; - - /** - * Whether or not the items (or any one item's action state) has changed since it was - * last fetched. - */ - private boolean mIsActionItemsStale; - - /** - * Default value for how added items should show in the action list. - */ - private int mDefaultShowAsAction = MenuItem.SHOW_AS_ACTION_NEVER; - - /** - * Current use case is Context Menus: As Views populate the context menu, each one has - * extra information that should be passed along. This is the current menu info that - * should be set on all items added to this menu. - */ - private ContextMenuInfo mCurrentMenuInfo; - - /** Header title for menu types that have a header (context and submenus) */ - CharSequence mHeaderTitle; - /** Header icon for menu types that have a header and support icons (context) */ - Drawable mHeaderIcon; - /** Header custom view for menu types that have a header and support custom views (context) */ - View mHeaderView; - - /** - * Contains the state of the View hierarchy for all menu views when the menu - * was frozen. - */ - //UNUSED private SparseArray mFrozenViewStates; - - /** - * Prevents onItemsChanged from doing its junk, useful for batching commands - * that may individually call onItemsChanged. - */ - private boolean mPreventDispatchingItemsChanged = false; - private boolean mItemsChangedWhileDispatchPrevented = false; - - private boolean mOptionalIconsVisible = false; - - private boolean mIsClosing = false; - - private ArrayList mTempShortcutItemList = new ArrayList(); - - private CopyOnWriteArrayList> mPresenters = - new CopyOnWriteArrayList>(); - - /** - * Currently expanded menu item; must be collapsed when we clear. - */ - private MenuItemImpl mExpandedItem; - - /** - * Called by menu to notify of close and selection changes. - */ - public interface Callback { - /** - * Called when a menu item is selected. - * @param menu The menu that is the parent of the item - * @param item The menu item that is selected - * @return whether the menu item selection was handled - */ - public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item); - - /** - * Called when the mode of the menu changes (for example, from icon to expanded). - * - * @param menu the menu that has changed modes - */ - public void onMenuModeChange(MenuBuilder menu); - } - - /** - * Called by menu items to execute their associated action - */ - public interface ItemInvoker { - public boolean invokeItem(MenuItemImpl item); - } - - public MenuBuilder(Context context) { - mContext = context; - mResources = context.getResources(); - - mItems = new ArrayList(); - - mVisibleItems = new ArrayList(); - mIsVisibleItemsStale = true; - - mActionItems = new ArrayList(); - mNonActionItems = new ArrayList(); - mIsActionItemsStale = true; - - setShortcutsVisibleInner(true); - } - - public MenuBuilder setDefaultShowAsAction(int defaultShowAsAction) { - mDefaultShowAsAction = defaultShowAsAction; - return this; - } - - /** - * Add a presenter to this menu. This will only hold a WeakReference; - * you do not need to explicitly remove a presenter, but you can using - * {@link #removeMenuPresenter(MenuPresenter)}. - * - * @param presenter The presenter to add - */ - public void addMenuPresenter(MenuPresenter presenter) { - mPresenters.add(new WeakReference(presenter)); - presenter.initForMenu(mContext, this); - mIsActionItemsStale = true; - } - - /** - * Remove a presenter from this menu. That presenter will no longer - * receive notifications of updates to this menu's data. - * - * @param presenter The presenter to remove - */ - public void removeMenuPresenter(MenuPresenter presenter) { - for (WeakReference ref : mPresenters) { - final MenuPresenter item = ref.get(); - if (item == null || item == presenter) { - mPresenters.remove(ref); - } - } - } - - private void dispatchPresenterUpdate(boolean cleared) { - if (mPresenters.isEmpty()) return; - - stopDispatchingItemsChanged(); - for (WeakReference ref : mPresenters) { - final MenuPresenter presenter = ref.get(); - if (presenter == null) { - mPresenters.remove(ref); - } else { - presenter.updateMenuView(cleared); - } - } - startDispatchingItemsChanged(); - } - - private boolean dispatchSubMenuSelected(SubMenuBuilder subMenu) { - if (mPresenters.isEmpty()) return false; - - boolean result = false; - - for (WeakReference ref : mPresenters) { - final MenuPresenter presenter = ref.get(); - if (presenter == null) { - mPresenters.remove(ref); - } else if (!result) { - result = presenter.onSubMenuSelected(subMenu); - } - } - return result; - } - - private void dispatchSaveInstanceState(Bundle outState) { - if (mPresenters.isEmpty()) return; - - SparseArray presenterStates = new SparseArray(); - - for (WeakReference ref : mPresenters) { - final MenuPresenter presenter = ref.get(); - if (presenter == null) { - mPresenters.remove(ref); - } else { - final int id = presenter.getId(); - if (id > 0) { - final Parcelable state = presenter.onSaveInstanceState(); - if (state != null) { - presenterStates.put(id, state); - } - } - } - } - - outState.putSparseParcelableArray(PRESENTER_KEY, presenterStates); - } - - private void dispatchRestoreInstanceState(Bundle state) { - SparseArray presenterStates = state.getSparseParcelableArray(PRESENTER_KEY); - - if (presenterStates == null || mPresenters.isEmpty()) return; - - for (WeakReference ref : mPresenters) { - final MenuPresenter presenter = ref.get(); - if (presenter == null) { - mPresenters.remove(ref); - } else { - final int id = presenter.getId(); - if (id > 0) { - Parcelable parcel = presenterStates.get(id); - if (parcel != null) { - presenter.onRestoreInstanceState(parcel); - } - } - } - } - } - - public void savePresenterStates(Bundle outState) { - dispatchSaveInstanceState(outState); - } - - public void restorePresenterStates(Bundle state) { - dispatchRestoreInstanceState(state); - } - - public void saveActionViewStates(Bundle outStates) { - SparseArray viewStates = null; - - final int itemCount = size(); - for (int i = 0; i < itemCount; i++) { - final MenuItem item = getItem(i); - final View v = item.getActionView(); - if (v != null && v.getId() != View.NO_ID) { - if (viewStates == null) { - viewStates = new SparseArray(); - } - v.saveHierarchyState(viewStates); - if (item.isActionViewExpanded()) { - outStates.putInt(EXPANDED_ACTION_VIEW_ID, item.getItemId()); - } - } - if (item.hasSubMenu()) { - final SubMenuBuilder subMenu = (SubMenuBuilder) item.getSubMenu(); - subMenu.saveActionViewStates(outStates); - } - } - - if (viewStates != null) { - outStates.putSparseParcelableArray(getActionViewStatesKey(), viewStates); - } - } - - public void restoreActionViewStates(Bundle states) { - if (states == null) { - return; - } - - SparseArray viewStates = states.getSparseParcelableArray( - getActionViewStatesKey()); - - final int itemCount = size(); - for (int i = 0; i < itemCount; i++) { - final MenuItem item = getItem(i); - final View v = item.getActionView(); - if (v != null && v.getId() != View.NO_ID) { - v.restoreHierarchyState(viewStates); - } - if (item.hasSubMenu()) { - final SubMenuBuilder subMenu = (SubMenuBuilder) item.getSubMenu(); - subMenu.restoreActionViewStates(states); - } - } - - final int expandedId = states.getInt(EXPANDED_ACTION_VIEW_ID); - if (expandedId > 0) { - MenuItem itemToExpand = findItem(expandedId); - if (itemToExpand != null) { - itemToExpand.expandActionView(); - } - } - } - - protected String getActionViewStatesKey() { - return ACTION_VIEW_STATES_KEY; - } - - public void setCallback(Callback cb) { - mCallback = cb; - } - - /** - * Adds an item to the menu. The other add methods funnel to this. - */ - private MenuItem addInternal(int group, int id, int categoryOrder, CharSequence title) { - final int ordering = getOrdering(categoryOrder); - - final MenuItemImpl item = new MenuItemImpl(this, group, id, categoryOrder, - ordering, title, mDefaultShowAsAction); - - if (mCurrentMenuInfo != null) { - // Pass along the current menu info - item.setMenuInfo(mCurrentMenuInfo); - } - - mItems.add(findInsertIndex(mItems, ordering), item); - onItemsChanged(true); - - return item; - } - - public MenuItem add(CharSequence title) { - return addInternal(0, 0, 0, title); - } - - public MenuItem add(int titleRes) { - return addInternal(0, 0, 0, mResources.getString(titleRes)); - } - - public MenuItem add(int group, int id, int categoryOrder, CharSequence title) { - return addInternal(group, id, categoryOrder, title); - } - - public MenuItem add(int group, int id, int categoryOrder, int title) { - return addInternal(group, id, categoryOrder, mResources.getString(title)); - } - - public SubMenu addSubMenu(CharSequence title) { - return addSubMenu(0, 0, 0, title); - } - - public SubMenu addSubMenu(int titleRes) { - return addSubMenu(0, 0, 0, mResources.getString(titleRes)); - } - - public SubMenu addSubMenu(int group, int id, int categoryOrder, CharSequence title) { - final MenuItemImpl item = (MenuItemImpl) addInternal(group, id, categoryOrder, title); - final SubMenuBuilder subMenu = new SubMenuBuilder(mContext, this, item); - item.setSubMenu(subMenu); - - return subMenu; - } - - public SubMenu addSubMenu(int group, int id, int categoryOrder, int title) { - return addSubMenu(group, id, categoryOrder, mResources.getString(title)); - } - - public int addIntentOptions(int group, int id, int categoryOrder, ComponentName caller, - Intent[] specifics, Intent intent, int flags, MenuItem[] outSpecificItems) { - PackageManager pm = mContext.getPackageManager(); - final List lri = - pm.queryIntentActivityOptions(caller, specifics, intent, 0); - final int N = lri != null ? lri.size() : 0; - - if ((flags & FLAG_APPEND_TO_GROUP) == 0) { - removeGroup(group); - } - - for (int i=0; i= 0) { - outSpecificItems[ri.specificIndex] = item; - } - } - - return N; - } - - public void removeItem(int id) { - removeItemAtInt(findItemIndex(id), true); - } - - public void removeGroup(int group) { - final int i = findGroupIndex(group); - - if (i >= 0) { - final int maxRemovable = mItems.size() - i; - int numRemoved = 0; - while ((numRemoved++ < maxRemovable) && (mItems.get(i).getGroupId() == group)) { - // Don't force update for each one, this method will do it at the end - removeItemAtInt(i, false); - } - - // Notify menu views - onItemsChanged(true); - } - } - - /** - * Remove the item at the given index and optionally forces menu views to - * update. - * - * @param index The index of the item to be removed. If this index is - * invalid an exception is thrown. - * @param updateChildrenOnMenuViews Whether to force update on menu views. - * Please make sure you eventually call this after your batch of - * removals. - */ - private void removeItemAtInt(int index, boolean updateChildrenOnMenuViews) { - if ((index < 0) || (index >= mItems.size())) return; - - mItems.remove(index); - - if (updateChildrenOnMenuViews) onItemsChanged(true); - } - - public void removeItemAt(int index) { - removeItemAtInt(index, true); - } - - public void clearAll() { - mPreventDispatchingItemsChanged = true; - clear(); - clearHeader(); - mPreventDispatchingItemsChanged = false; - mItemsChangedWhileDispatchPrevented = false; - onItemsChanged(true); - } - - public void clear() { - if (mExpandedItem != null) { - collapseItemActionView(mExpandedItem); - } - mItems.clear(); - - onItemsChanged(true); - } - - void setExclusiveItemChecked(MenuItem item) { - final int group = item.getGroupId(); - - final int N = mItems.size(); - for (int i = 0; i < N; i++) { - MenuItemImpl curItem = mItems.get(i); - if (curItem.getGroupId() == group) { - if (!curItem.isExclusiveCheckable()) continue; - if (!curItem.isCheckable()) continue; - - // Check the item meant to be checked, uncheck the others (that are in the group) - curItem.setCheckedInt(curItem == item); - } - } - } - - public void setGroupCheckable(int group, boolean checkable, boolean exclusive) { - final int N = mItems.size(); - - for (int i = 0; i < N; i++) { - MenuItemImpl item = mItems.get(i); - if (item.getGroupId() == group) { - item.setExclusiveCheckable(exclusive); - item.setCheckable(checkable); - } - } - } - - public void setGroupVisible(int group, boolean visible) { - final int N = mItems.size(); - - // We handle the notification of items being changed ourselves, so we use setVisibleInt rather - // than setVisible and at the end notify of items being changed - - boolean changedAtLeastOneItem = false; - for (int i = 0; i < N; i++) { - MenuItemImpl item = mItems.get(i); - if (item.getGroupId() == group) { - if (item.setVisibleInt(visible)) changedAtLeastOneItem = true; - } - } - - if (changedAtLeastOneItem) onItemsChanged(true); - } - - public void setGroupEnabled(int group, boolean enabled) { - final int N = mItems.size(); - - for (int i = 0; i < N; i++) { - MenuItemImpl item = mItems.get(i); - if (item.getGroupId() == group) { - item.setEnabled(enabled); - } - } - } - - public boolean hasVisibleItems() { - final int size = size(); - - for (int i = 0; i < size; i++) { - MenuItemImpl item = mItems.get(i); - if (item.isVisible()) { - return true; - } - } - - return false; - } - - public MenuItem findItem(int id) { - final int size = size(); - for (int i = 0; i < size; i++) { - MenuItemImpl item = mItems.get(i); - if (item.getItemId() == id) { - return item; - } else if (item.hasSubMenu()) { - MenuItem possibleItem = item.getSubMenu().findItem(id); - - if (possibleItem != null) { - return possibleItem; - } - } - } - - return null; - } - - public int findItemIndex(int id) { - final int size = size(); - - for (int i = 0; i < size; i++) { - MenuItemImpl item = mItems.get(i); - if (item.getItemId() == id) { - return i; - } - } - - return -1; - } - - public int findGroupIndex(int group) { - return findGroupIndex(group, 0); - } - - public int findGroupIndex(int group, int start) { - final int size = size(); - - if (start < 0) { - start = 0; - } - - for (int i = start; i < size; i++) { - final MenuItemImpl item = mItems.get(i); - - if (item.getGroupId() == group) { - return i; - } - } - - return -1; - } - - public int size() { - return mItems.size(); - } - - /** {@inheritDoc} */ - public MenuItem getItem(int index) { - return mItems.get(index); - } - - public boolean isShortcutKey(int keyCode, KeyEvent event) { - return findItemWithShortcutForKey(keyCode, event) != null; - } - - public void setQwertyMode(boolean isQwerty) { - mQwertyMode = isQwerty; - - onItemsChanged(false); - } - - /** - * Returns the ordering across all items. This will grab the category from - * the upper bits, find out how to order the category with respect to other - * categories, and combine it with the lower bits. - * - * @param categoryOrder The category order for a particular item (if it has - * not been or/add with a category, the default category is - * assumed). - * @return An ordering integer that can be used to order this item across - * all the items (even from other categories). - */ - private static int getOrdering(int categoryOrder) { - final int index = (categoryOrder & CATEGORY_MASK) >> CATEGORY_SHIFT; - - if (index < 0 || index >= sCategoryToOrder.length) { - throw new IllegalArgumentException("order does not contain a valid category."); - } - - return (sCategoryToOrder[index] << CATEGORY_SHIFT) | (categoryOrder & USER_MASK); - } - - /** - * @return whether the menu shortcuts are in qwerty mode or not - */ - boolean isQwertyMode() { - return mQwertyMode; - } - - /** - * Sets whether the shortcuts should be visible on menus. Devices without hardware - * key input will never make shortcuts visible even if this method is passed 'true'. - * - * @param shortcutsVisible Whether shortcuts should be visible (if true and a - * menu item does not have a shortcut defined, that item will - * still NOT show a shortcut) - */ - public void setShortcutsVisible(boolean shortcutsVisible) { - if (mShortcutsVisible == shortcutsVisible) return; - - setShortcutsVisibleInner(shortcutsVisible); - onItemsChanged(false); - } - - private void setShortcutsVisibleInner(boolean shortcutsVisible) { - mShortcutsVisible = shortcutsVisible - && mResources.getConfiguration().keyboard != Configuration.KEYBOARD_NOKEYS - && mResources.getBoolean( - R.bool.abs__config_showMenuShortcutsWhenKeyboardPresent); - } - - /** - * @return Whether shortcuts should be visible on menus. - */ - public boolean isShortcutsVisible() { - return mShortcutsVisible; - } - - Resources getResources() { - return mResources; - } - - public Context getContext() { - return mContext; - } - - boolean dispatchMenuItemSelected(MenuBuilder menu, MenuItem item) { - return mCallback != null && mCallback.onMenuItemSelected(menu, item); - } - - /** - * Dispatch a mode change event to this menu's callback. - */ - public void changeMenuMode() { - if (mCallback != null) { - mCallback.onMenuModeChange(this); - } - } - - private static int findInsertIndex(ArrayList items, int ordering) { - for (int i = items.size() - 1; i >= 0; i--) { - MenuItemImpl item = items.get(i); - if (item.getOrdering() <= ordering) { - return i + 1; - } - } - - return 0; - } - - public boolean performShortcut(int keyCode, KeyEvent event, int flags) { - final MenuItemImpl item = findItemWithShortcutForKey(keyCode, event); - - boolean handled = false; - - if (item != null) { - handled = performItemAction(item, flags); - } - - if ((flags & FLAG_ALWAYS_PERFORM_CLOSE) != 0) { - close(true); - } - - return handled; - } - - /* - * This function will return all the menu and sub-menu items that can - * be directly (the shortcut directly corresponds) and indirectly - * (the ALT-enabled char corresponds to the shortcut) associated - * with the keyCode. - */ - @SuppressWarnings("deprecation") - void findItemsWithShortcutForKey(List items, int keyCode, KeyEvent event) { - final boolean qwerty = isQwertyMode(); - final int metaState = event.getMetaState(); - final KeyCharacterMap.KeyData possibleChars = new KeyCharacterMap.KeyData(); - // Get the chars associated with the keyCode (i.e using any chording combo) - final boolean isKeyCodeMapped = event.getKeyData(possibleChars); - // The delete key is not mapped to '\b' so we treat it specially - if (!isKeyCodeMapped && (keyCode != KeyEvent.KEYCODE_DEL)) { - return; - } - - // Look for an item whose shortcut is this key. - final int N = mItems.size(); - for (int i = 0; i < N; i++) { - MenuItemImpl item = mItems.get(i); - if (item.hasSubMenu()) { - ((MenuBuilder)item.getSubMenu()).findItemsWithShortcutForKey(items, keyCode, event); - } - final char shortcutChar = qwerty ? item.getAlphabeticShortcut() : item.getNumericShortcut(); - if (((metaState & (KeyEvent.META_SHIFT_ON | KeyEvent.META_SYM_ON)) == 0) && - (shortcutChar != 0) && - (shortcutChar == possibleChars.meta[0] - || shortcutChar == possibleChars.meta[2] - || (qwerty && shortcutChar == '\b' && - keyCode == KeyEvent.KEYCODE_DEL)) && - item.isEnabled()) { - items.add(item); - } - } - } - - /* - * We want to return the menu item associated with the key, but if there is no - * ambiguity (i.e. there is only one menu item corresponding to the key) we want - * to return it even if it's not an exact match; this allow the user to - * _not_ use the ALT key for example, making the use of shortcuts slightly more - * user-friendly. An example is on the G1, '!' and '1' are on the same key, and - * in Gmail, Menu+1 will trigger Menu+! (the actual shortcut). - * - * On the other hand, if two (or more) shortcuts corresponds to the same key, - * we have to only return the exact match. - */ - @SuppressWarnings("deprecation") - MenuItemImpl findItemWithShortcutForKey(int keyCode, KeyEvent event) { - // Get all items that can be associated directly or indirectly with the keyCode - ArrayList items = mTempShortcutItemList; - items.clear(); - findItemsWithShortcutForKey(items, keyCode, event); - - if (items.isEmpty()) { - return null; - } - - final int metaState = event.getMetaState(); - final KeyCharacterMap.KeyData possibleChars = new KeyCharacterMap.KeyData(); - // Get the chars associated with the keyCode (i.e using any chording combo) - event.getKeyData(possibleChars); - - // If we have only one element, we can safely returns it - final int size = items.size(); - if (size == 1) { - return items.get(0); - } - - final boolean qwerty = isQwertyMode(); - // If we found more than one item associated with the key, - // we have to return the exact match - for (int i = 0; i < size; i++) { - final MenuItemImpl item = items.get(i); - final char shortcutChar = qwerty ? item.getAlphabeticShortcut() : - item.getNumericShortcut(); - if ((shortcutChar == possibleChars.meta[0] && - (metaState & KeyEvent.META_ALT_ON) == 0) - || (shortcutChar == possibleChars.meta[2] && - (metaState & KeyEvent.META_ALT_ON) != 0) - || (qwerty && shortcutChar == '\b' && - keyCode == KeyEvent.KEYCODE_DEL)) { - return item; - } - } - return null; - } - - public boolean performIdentifierAction(int id, int flags) { - // Look for an item whose identifier is the id. - return performItemAction(findItem(id), flags); - } - - public boolean performItemAction(MenuItem item, int flags) { - MenuItemImpl itemImpl = (MenuItemImpl) item; - - if (itemImpl == null || !itemImpl.isEnabled()) { - return false; - } - - boolean invoked = itemImpl.invoke(); - - if (itemImpl.hasCollapsibleActionView()) { - invoked |= itemImpl.expandActionView(); - if (invoked) close(true); - } else if (item.hasSubMenu()) { - close(false); - - final SubMenuBuilder subMenu = (SubMenuBuilder) item.getSubMenu(); - final ActionProvider provider = item.getActionProvider(); - if (provider != null && provider.hasSubMenu()) { - provider.onPrepareSubMenu(subMenu); - } - invoked |= dispatchSubMenuSelected(subMenu); - if (!invoked) close(true); - } else { - if ((flags & FLAG_PERFORM_NO_CLOSE) == 0) { - close(true); - } - } - - return invoked; - } - - /** - * Closes the visible menu. - * - * @param allMenusAreClosing Whether the menus are completely closing (true), - * or whether there is another menu coming in this menu's place - * (false). For example, if the menu is closing because a - * sub menu is about to be shown, allMenusAreClosing - * is false. - */ - final void close(boolean allMenusAreClosing) { - if (mIsClosing) return; - - mIsClosing = true; - for (WeakReference ref : mPresenters) { - final MenuPresenter presenter = ref.get(); - if (presenter == null) { - mPresenters.remove(ref); - } else { - presenter.onCloseMenu(this, allMenusAreClosing); - } - } - mIsClosing = false; - } - - /** {@inheritDoc} */ - public void close() { - close(true); - } - - /** - * Called when an item is added or removed. - * - * @param structureChanged true if the menu structure changed, - * false if only item properties changed. - * (Visibility is a structural property since it affects layout.) - */ - void onItemsChanged(boolean structureChanged) { - if (!mPreventDispatchingItemsChanged) { - if (structureChanged) { - mIsVisibleItemsStale = true; - mIsActionItemsStale = true; - } - - dispatchPresenterUpdate(structureChanged); - } else { - mItemsChangedWhileDispatchPrevented = true; - } - } - - /** - * Stop dispatching item changed events to presenters until - * {@link #startDispatchingItemsChanged()} is called. Useful when - * many menu operations are going to be performed as a batch. - */ - public void stopDispatchingItemsChanged() { - if (!mPreventDispatchingItemsChanged) { - mPreventDispatchingItemsChanged = true; - mItemsChangedWhileDispatchPrevented = false; - } - } - - public void startDispatchingItemsChanged() { - mPreventDispatchingItemsChanged = false; - - if (mItemsChangedWhileDispatchPrevented) { - mItemsChangedWhileDispatchPrevented = false; - onItemsChanged(true); - } - } - - /** - * Called by {@link MenuItemImpl} when its visible flag is changed. - * @param item The item that has gone through a visibility change. - */ - void onItemVisibleChanged(MenuItemImpl item) { - // Notify of items being changed - mIsVisibleItemsStale = true; - onItemsChanged(true); - } - - /** - * Called by {@link MenuItemImpl} when its action request status is changed. - * @param item The item that has gone through a change in action request status. - */ - void onItemActionRequestChanged(MenuItemImpl item) { - // Notify of items being changed - mIsActionItemsStale = true; - onItemsChanged(true); - } - - ArrayList getVisibleItems() { - if (!mIsVisibleItemsStale) return mVisibleItems; - - // Refresh the visible items - mVisibleItems.clear(); - - final int itemsSize = mItems.size(); - MenuItemImpl item; - for (int i = 0; i < itemsSize; i++) { - item = mItems.get(i); - if (item.isVisible()) mVisibleItems.add(item); - } - - mIsVisibleItemsStale = false; - mIsActionItemsStale = true; - - return mVisibleItems; - } - - /** - * This method determines which menu items get to be 'action items' that will appear - * in an action bar and which items should be 'overflow items' in a secondary menu. - * The rules are as follows: - * - *

Items are considered for inclusion in the order specified within the menu. - * There is a limit of mMaxActionItems as a total count, optionally including the overflow - * menu button itself. This is a soft limit; if an item shares a group ID with an item - * previously included as an action item, the new item will stay with its group and become - * an action item itself even if it breaks the max item count limit. This is done to - * limit the conceptual complexity of the items presented within an action bar. Only a few - * unrelated concepts should be presented to the user in this space, and groups are treated - * as a single concept. - * - *

There is also a hard limit of consumed measurable space: mActionWidthLimit. This - * limit may be broken by a single item that exceeds the remaining space, but no further - * items may be added. If an item that is part of a group cannot fit within the remaining - * measured width, the entire group will be demoted to overflow. This is done to ensure room - * for navigation and other affordances in the action bar as well as reduce general UI clutter. - * - *

The space freed by demoting a full group cannot be consumed by future menu items. - * Once items begin to overflow, all future items become overflow items as well. This is - * to avoid inadvertent reordering that may break the app's intended design. - */ - public void flagActionItems() { - if (!mIsActionItemsStale) { - return; - } - - // Presenters flag action items as needed. - boolean flagged = false; - for (WeakReference ref : mPresenters) { - final MenuPresenter presenter = ref.get(); - if (presenter == null) { - mPresenters.remove(ref); - } else { - flagged |= presenter.flagActionItems(); - } - } - - if (flagged) { - mActionItems.clear(); - mNonActionItems.clear(); - ArrayList visibleItems = getVisibleItems(); - final int itemsSize = visibleItems.size(); - for (int i = 0; i < itemsSize; i++) { - MenuItemImpl item = visibleItems.get(i); - if (item.isActionButton()) { - mActionItems.add(item); - } else { - mNonActionItems.add(item); - } - } - } else { - // Nobody flagged anything, everything is a non-action item. - // (This happens during a first pass with no action-item presenters.) - mActionItems.clear(); - mNonActionItems.clear(); - mNonActionItems.addAll(getVisibleItems()); - } - mIsActionItemsStale = false; - } - - ArrayList getActionItems() { - flagActionItems(); - return mActionItems; - } - - ArrayList getNonActionItems() { - flagActionItems(); - return mNonActionItems; - } - - public void clearHeader() { - mHeaderIcon = null; - mHeaderTitle = null; - mHeaderView = null; - - onItemsChanged(false); - } - - private void setHeaderInternal(final int titleRes, final CharSequence title, final int iconRes, - final Drawable icon, final View view) { - final Resources r = getResources(); - - if (view != null) { - mHeaderView = view; - - // If using a custom view, then the title and icon aren't used - mHeaderTitle = null; - mHeaderIcon = null; - } else { - if (titleRes > 0) { - mHeaderTitle = r.getText(titleRes); - } else if (title != null) { - mHeaderTitle = title; - } - - if (iconRes > 0) { - mHeaderIcon = r.getDrawable(iconRes); - } else if (icon != null) { - mHeaderIcon = icon; - } - - // If using the title or icon, then a custom view isn't used - mHeaderView = null; - } - - // Notify of change - onItemsChanged(false); - } - - /** - * Sets the header's title. This replaces the header view. Called by the - * builder-style methods of subclasses. - * - * @param title The new title. - * @return This MenuBuilder so additional setters can be called. - */ - protected MenuBuilder setHeaderTitleInt(CharSequence title) { - setHeaderInternal(0, title, 0, null, null); - return this; - } - - /** - * Sets the header's title. This replaces the header view. Called by the - * builder-style methods of subclasses. - * - * @param titleRes The new title (as a resource ID). - * @return This MenuBuilder so additional setters can be called. - */ - protected MenuBuilder setHeaderTitleInt(int titleRes) { - setHeaderInternal(titleRes, null, 0, null, null); - return this; - } - - /** - * Sets the header's icon. This replaces the header view. Called by the - * builder-style methods of subclasses. - * - * @param icon The new icon. - * @return This MenuBuilder so additional setters can be called. - */ - protected MenuBuilder setHeaderIconInt(Drawable icon) { - setHeaderInternal(0, null, 0, icon, null); - return this; - } - - /** - * Sets the header's icon. This replaces the header view. Called by the - * builder-style methods of subclasses. - * - * @param iconRes The new icon (as a resource ID). - * @return This MenuBuilder so additional setters can be called. - */ - protected MenuBuilder setHeaderIconInt(int iconRes) { - setHeaderInternal(0, null, iconRes, null, null); - return this; - } - - /** - * Sets the header's view. This replaces the title and icon. Called by the - * builder-style methods of subclasses. - * - * @param view The new view. - * @return This MenuBuilder so additional setters can be called. - */ - protected MenuBuilder setHeaderViewInt(View view) { - setHeaderInternal(0, null, 0, null, view); - return this; - } - - public CharSequence getHeaderTitle() { - return mHeaderTitle; - } - - public Drawable getHeaderIcon() { - return mHeaderIcon; - } - - public View getHeaderView() { - return mHeaderView; - } - - /** - * Gets the root menu (if this is a submenu, find its root menu). - * @return The root menu. - */ - public MenuBuilder getRootMenu() { - return this; - } - - /** - * Sets the current menu info that is set on all items added to this menu - * (until this is called again with different menu info, in which case that - * one will be added to all subsequent item additions). - * - * @param menuInfo The extra menu information to add. - */ - public void setCurrentMenuInfo(ContextMenuInfo menuInfo) { - mCurrentMenuInfo = menuInfo; - } - - void setOptionalIconsVisible(boolean visible) { - mOptionalIconsVisible = visible; - } - - boolean getOptionalIconsVisible() { - return mOptionalIconsVisible; - } - - public boolean expandItemActionView(MenuItemImpl item) { - if (mPresenters.isEmpty()) return false; - - boolean expanded = false; - - stopDispatchingItemsChanged(); - for (WeakReference ref : mPresenters) { - final MenuPresenter presenter = ref.get(); - if (presenter == null) { - mPresenters.remove(ref); - } else if ((expanded = presenter.expandItemActionView(this, item))) { - break; - } - } - startDispatchingItemsChanged(); - - if (expanded) { - mExpandedItem = item; - } - return expanded; - } - - public boolean collapseItemActionView(MenuItemImpl item) { - if (mPresenters.isEmpty() || mExpandedItem != item) return false; - - boolean collapsed = false; - - stopDispatchingItemsChanged(); - for (WeakReference ref : mPresenters) { - final MenuPresenter presenter = ref.get(); - if (presenter == null) { - mPresenters.remove(ref); - } else if ((collapsed = presenter.collapseItemActionView(this, item))) { - break; - } - } - startDispatchingItemsChanged(); - - if (collapsed) { - mExpandedItem = null; - } - return collapsed; - } - - public MenuItemImpl getExpandedItem() { - return mExpandedItem; - } - - public boolean bindNativeOverflow(android.view.Menu menu, android.view.MenuItem.OnMenuItemClickListener listener, HashMap map) { - final List nonActionItems = getNonActionItems(); - if (nonActionItems == null || nonActionItems.size() == 0) { - return false; - } - - boolean visible = false; - menu.clear(); - for (MenuItemImpl nonActionItem : nonActionItems) { - if (!nonActionItem.isVisible()) { - continue; - } - visible = true; - - android.view.MenuItem nativeItem; - if (nonActionItem.hasSubMenu()) { - android.view.SubMenu nativeSub = menu.addSubMenu(nonActionItem.getGroupId(), nonActionItem.getItemId(), - nonActionItem.getOrder(), nonActionItem.getTitle()); - - SubMenuBuilder subMenu = (SubMenuBuilder)nonActionItem.getSubMenu(); - for (MenuItemImpl subItem : subMenu.getVisibleItems()) { - android.view.MenuItem nativeSubItem = nativeSub.add(subItem.getGroupId(), subItem.getItemId(), - subItem.getOrder(), subItem.getTitle()); - - nativeSubItem.setIcon(subItem.getIcon()); - nativeSubItem.setOnMenuItemClickListener(listener); - nativeSubItem.setEnabled(subItem.isEnabled()); - nativeSubItem.setIntent(subItem.getIntent()); - nativeSubItem.setNumericShortcut(subItem.getNumericShortcut()); - nativeSubItem.setAlphabeticShortcut(subItem.getAlphabeticShortcut()); - nativeSubItem.setTitleCondensed(subItem.getTitleCondensed()); - nativeSubItem.setCheckable(subItem.isCheckable()); - nativeSubItem.setChecked(subItem.isChecked()); - - if (subItem.isExclusiveCheckable()) { - nativeSub.setGroupCheckable(subItem.getGroupId(), true, true); - } - - map.put(nativeSubItem, subItem); - } - - nativeItem = nativeSub.getItem(); - } else { - nativeItem = menu.add(nonActionItem.getGroupId(), nonActionItem.getItemId(), - nonActionItem.getOrder(), nonActionItem.getTitle()); - } - nativeItem.setIcon(nonActionItem.getIcon()); - nativeItem.setOnMenuItemClickListener(listener); - nativeItem.setEnabled(nonActionItem.isEnabled()); - nativeItem.setIntent(nonActionItem.getIntent()); - nativeItem.setNumericShortcut(nonActionItem.getNumericShortcut()); - nativeItem.setAlphabeticShortcut(nonActionItem.getAlphabeticShortcut()); - nativeItem.setTitleCondensed(nonActionItem.getTitleCondensed()); - nativeItem.setCheckable(nonActionItem.isCheckable()); - nativeItem.setChecked(nonActionItem.isChecked()); - - if (nonActionItem.isExclusiveCheckable()) { - menu.setGroupCheckable(nonActionItem.getGroupId(), true, true); - } - - map.put(nativeItem, nonActionItem); - } - return visible; - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/MenuItemImpl.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/MenuItemImpl.java deleted file mode 100644 index f5359fb40..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/MenuItemImpl.java +++ /dev/null @@ -1,647 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.view.menu; - -import android.content.ActivityNotFoundException; -import android.content.Context; -import android.content.Intent; -import android.graphics.drawable.Drawable; -import android.util.Log; -import android.view.ContextMenu.ContextMenuInfo; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewDebug; -import android.widget.LinearLayout; - -import com.actionbarsherlock.view.ActionProvider; -import com.actionbarsherlock.view.MenuItem; -import com.actionbarsherlock.view.SubMenu; - -/** - * @hide - */ -public final class MenuItemImpl implements MenuItem { - private static final String TAG = "MenuItemImpl"; - - private static final int SHOW_AS_ACTION_MASK = SHOW_AS_ACTION_NEVER | - SHOW_AS_ACTION_IF_ROOM | - SHOW_AS_ACTION_ALWAYS; - - private final int mId; - private final int mGroup; - private final int mCategoryOrder; - private final int mOrdering; - private CharSequence mTitle; - private CharSequence mTitleCondensed; - private Intent mIntent; - private char mShortcutNumericChar; - private char mShortcutAlphabeticChar; - - /** The icon's drawable which is only created as needed */ - private Drawable mIconDrawable; - /** - * The icon's resource ID which is used to get the Drawable when it is - * needed (if the Drawable isn't already obtained--only one of the two is - * needed). - */ - private int mIconResId = NO_ICON; - - /** The menu to which this item belongs */ - private MenuBuilder mMenu; - /** If this item should launch a sub menu, this is the sub menu to launch */ - private SubMenuBuilder mSubMenu; - - private Runnable mItemCallback; - private MenuItem.OnMenuItemClickListener mClickListener; - - private int mFlags = ENABLED; - private static final int CHECKABLE = 0x00000001; - private static final int CHECKED = 0x00000002; - private static final int EXCLUSIVE = 0x00000004; - private static final int HIDDEN = 0x00000008; - private static final int ENABLED = 0x00000010; - private static final int IS_ACTION = 0x00000020; - - private int mShowAsAction = SHOW_AS_ACTION_NEVER; - - private View mActionView; - private ActionProvider mActionProvider; - private OnActionExpandListener mOnActionExpandListener; - private boolean mIsActionViewExpanded = false; - - /** Used for the icon resource ID if this item does not have an icon */ - static final int NO_ICON = 0; - - /** - * Current use case is for context menu: Extra information linked to the - * View that added this item to the context menu. - */ - private ContextMenuInfo mMenuInfo; - - private static String sPrependShortcutLabel; - private static String sEnterShortcutLabel; - private static String sDeleteShortcutLabel; - private static String sSpaceShortcutLabel; - - - /** - * Instantiates this menu item. - * - * @param menu - * @param group Item ordering grouping control. The item will be added after - * all other items whose order is <= this number, and before any - * that are larger than it. This can also be used to define - * groups of items for batch state changes. Normally use 0. - * @param id Unique item ID. Use 0 if you do not need a unique ID. - * @param categoryOrder The ordering for this item. - * @param title The text to display for the item. - */ - MenuItemImpl(MenuBuilder menu, int group, int id, int categoryOrder, int ordering, - CharSequence title, int showAsAction) { - - /* TODO if (sPrependShortcutLabel == null) { - // This is instantiated from the UI thread, so no chance of sync issues - sPrependShortcutLabel = menu.getContext().getResources().getString( - com.android.internal.R.string.prepend_shortcut_label); - sEnterShortcutLabel = menu.getContext().getResources().getString( - com.android.internal.R.string.menu_enter_shortcut_label); - sDeleteShortcutLabel = menu.getContext().getResources().getString( - com.android.internal.R.string.menu_delete_shortcut_label); - sSpaceShortcutLabel = menu.getContext().getResources().getString( - com.android.internal.R.string.menu_space_shortcut_label); - }*/ - - mMenu = menu; - mId = id; - mGroup = group; - mCategoryOrder = categoryOrder; - mOrdering = ordering; - mTitle = title; - mShowAsAction = showAsAction; - } - - /** - * Invokes the item by calling various listeners or callbacks. - * - * @return true if the invocation was handled, false otherwise - */ - public boolean invoke() { - if (mClickListener != null && - mClickListener.onMenuItemClick(this)) { - return true; - } - - if (mMenu.dispatchMenuItemSelected(mMenu.getRootMenu(), this)) { - return true; - } - - if (mItemCallback != null) { - mItemCallback.run(); - return true; - } - - if (mIntent != null) { - try { - mMenu.getContext().startActivity(mIntent); - return true; - } catch (ActivityNotFoundException e) { - Log.e(TAG, "Can't find activity to handle intent; ignoring", e); - } - } - - if (mActionProvider != null && mActionProvider.onPerformDefaultAction()) { - return true; - } - - return false; - } - - public boolean isEnabled() { - return (mFlags & ENABLED) != 0; - } - - public MenuItem setEnabled(boolean enabled) { - if (enabled) { - mFlags |= ENABLED; - } else { - mFlags &= ~ENABLED; - } - - mMenu.onItemsChanged(false); - - return this; - } - - public int getGroupId() { - return mGroup; - } - - @ViewDebug.CapturedViewProperty - public int getItemId() { - return mId; - } - - public int getOrder() { - return mCategoryOrder; - } - - public int getOrdering() { - return mOrdering; - } - - public Intent getIntent() { - return mIntent; - } - - public MenuItem setIntent(Intent intent) { - mIntent = intent; - return this; - } - - Runnable getCallback() { - return mItemCallback; - } - - public MenuItem setCallback(Runnable callback) { - mItemCallback = callback; - return this; - } - - public char getAlphabeticShortcut() { - return mShortcutAlphabeticChar; - } - - public MenuItem setAlphabeticShortcut(char alphaChar) { - if (mShortcutAlphabeticChar == alphaChar) return this; - - mShortcutAlphabeticChar = Character.toLowerCase(alphaChar); - - mMenu.onItemsChanged(false); - - return this; - } - - public char getNumericShortcut() { - return mShortcutNumericChar; - } - - public MenuItem setNumericShortcut(char numericChar) { - if (mShortcutNumericChar == numericChar) return this; - - mShortcutNumericChar = numericChar; - - mMenu.onItemsChanged(false); - - return this; - } - - public MenuItem setShortcut(char numericChar, char alphaChar) { - mShortcutNumericChar = numericChar; - mShortcutAlphabeticChar = Character.toLowerCase(alphaChar); - - mMenu.onItemsChanged(false); - - return this; - } - - /** - * @return The active shortcut (based on QWERTY-mode of the menu). - */ - char getShortcut() { - return (mMenu.isQwertyMode() ? mShortcutAlphabeticChar : mShortcutNumericChar); - } - - /** - * @return The label to show for the shortcut. This includes the chording - * key (for example 'Menu+a'). Also, any non-human readable - * characters should be human readable (for example 'Menu+enter'). - */ - String getShortcutLabel() { - - char shortcut = getShortcut(); - if (shortcut == 0) { - return ""; - } - - StringBuilder sb = new StringBuilder(sPrependShortcutLabel); - switch (shortcut) { - - case '\n': - sb.append(sEnterShortcutLabel); - break; - - case '\b': - sb.append(sDeleteShortcutLabel); - break; - - case ' ': - sb.append(sSpaceShortcutLabel); - break; - - default: - sb.append(shortcut); - break; - } - - return sb.toString(); - } - - /** - * @return Whether this menu item should be showing shortcuts (depends on - * whether the menu should show shortcuts and whether this item has - * a shortcut defined) - */ - boolean shouldShowShortcut() { - // Show shortcuts if the menu is supposed to show shortcuts AND this item has a shortcut - return mMenu.isShortcutsVisible() && (getShortcut() != 0); - } - - public SubMenu getSubMenu() { - return mSubMenu; - } - - public boolean hasSubMenu() { - return mSubMenu != null; - } - - void setSubMenu(SubMenuBuilder subMenu) { - mSubMenu = subMenu; - - subMenu.setHeaderTitle(getTitle()); - } - - @ViewDebug.CapturedViewProperty - public CharSequence getTitle() { - return mTitle; - } - - /** - * Gets the title for a particular {@link ItemView} - * - * @param itemView The ItemView that is receiving the title - * @return Either the title or condensed title based on what the ItemView - * prefers - */ - CharSequence getTitleForItemView(MenuView.ItemView itemView) { - return ((itemView != null) && itemView.prefersCondensedTitle()) - ? getTitleCondensed() - : getTitle(); - } - - public MenuItem setTitle(CharSequence title) { - mTitle = title; - - mMenu.onItemsChanged(false); - - if (mSubMenu != null) { - mSubMenu.setHeaderTitle(title); - } - - return this; - } - - public MenuItem setTitle(int title) { - return setTitle(mMenu.getContext().getString(title)); - } - - public CharSequence getTitleCondensed() { - return mTitleCondensed != null ? mTitleCondensed : mTitle; - } - - public MenuItem setTitleCondensed(CharSequence title) { - mTitleCondensed = title; - - // Could use getTitle() in the loop below, but just cache what it would do here - if (title == null) { - title = mTitle; - } - - mMenu.onItemsChanged(false); - - return this; - } - - public Drawable getIcon() { - if (mIconDrawable != null) { - return mIconDrawable; - } - - if (mIconResId != NO_ICON) { - return mMenu.getResources().getDrawable(mIconResId); - } - - return null; - } - - public MenuItem setIcon(Drawable icon) { - mIconResId = NO_ICON; - mIconDrawable = icon; - mMenu.onItemsChanged(false); - - return this; - } - - public MenuItem setIcon(int iconResId) { - mIconDrawable = null; - mIconResId = iconResId; - - // If we have a view, we need to push the Drawable to them - mMenu.onItemsChanged(false); - - return this; - } - - public boolean isCheckable() { - return (mFlags & CHECKABLE) == CHECKABLE; - } - - public MenuItem setCheckable(boolean checkable) { - final int oldFlags = mFlags; - mFlags = (mFlags & ~CHECKABLE) | (checkable ? CHECKABLE : 0); - if (oldFlags != mFlags) { - mMenu.onItemsChanged(false); - } - - return this; - } - - public void setExclusiveCheckable(boolean exclusive) { - mFlags = (mFlags & ~EXCLUSIVE) | (exclusive ? EXCLUSIVE : 0); - } - - public boolean isExclusiveCheckable() { - return (mFlags & EXCLUSIVE) != 0; - } - - public boolean isChecked() { - return (mFlags & CHECKED) == CHECKED; - } - - public MenuItem setChecked(boolean checked) { - if ((mFlags & EXCLUSIVE) != 0) { - // Call the method on the Menu since it knows about the others in this - // exclusive checkable group - mMenu.setExclusiveItemChecked(this); - } else { - setCheckedInt(checked); - } - - return this; - } - - void setCheckedInt(boolean checked) { - final int oldFlags = mFlags; - mFlags = (mFlags & ~CHECKED) | (checked ? CHECKED : 0); - if (oldFlags != mFlags) { - mMenu.onItemsChanged(false); - } - } - - public boolean isVisible() { - return (mFlags & HIDDEN) == 0; - } - - /** - * Changes the visibility of the item. This method DOES NOT notify the - * parent menu of a change in this item, so this should only be called from - * methods that will eventually trigger this change. If unsure, use {@link #setVisible(boolean)} - * instead. - * - * @param shown Whether to show (true) or hide (false). - * @return Whether the item's shown state was changed - */ - boolean setVisibleInt(boolean shown) { - final int oldFlags = mFlags; - mFlags = (mFlags & ~HIDDEN) | (shown ? 0 : HIDDEN); - return oldFlags != mFlags; - } - - public MenuItem setVisible(boolean shown) { - // Try to set the shown state to the given state. If the shown state was changed - // (i.e. the previous state isn't the same as given state), notify the parent menu that - // the shown state has changed for this item - if (setVisibleInt(shown)) mMenu.onItemVisibleChanged(this); - - return this; - } - - public MenuItem setOnMenuItemClickListener(MenuItem.OnMenuItemClickListener clickListener) { - mClickListener = clickListener; - return this; - } - - @Override - public String toString() { - return mTitle.toString(); - } - - void setMenuInfo(ContextMenuInfo menuInfo) { - mMenuInfo = menuInfo; - } - - public ContextMenuInfo getMenuInfo() { - return mMenuInfo; - } - - public void actionFormatChanged() { - mMenu.onItemActionRequestChanged(this); - } - - /** - * @return Whether the menu should show icons for menu items. - */ - public boolean shouldShowIcon() { - return mMenu.getOptionalIconsVisible(); - } - - public boolean isActionButton() { - return (mFlags & IS_ACTION) == IS_ACTION; - } - - public boolean requestsActionButton() { - return (mShowAsAction & SHOW_AS_ACTION_IF_ROOM) == SHOW_AS_ACTION_IF_ROOM; - } - - public boolean requiresActionButton() { - return (mShowAsAction & SHOW_AS_ACTION_ALWAYS) == SHOW_AS_ACTION_ALWAYS; - } - - public void setIsActionButton(boolean isActionButton) { - if (isActionButton) { - mFlags |= IS_ACTION; - } else { - mFlags &= ~IS_ACTION; - } - } - - public boolean showsTextAsAction() { - return (mShowAsAction & SHOW_AS_ACTION_WITH_TEXT) == SHOW_AS_ACTION_WITH_TEXT; - } - - public void setShowAsAction(int actionEnum) { - switch (actionEnum & SHOW_AS_ACTION_MASK) { - case SHOW_AS_ACTION_ALWAYS: - case SHOW_AS_ACTION_IF_ROOM: - case SHOW_AS_ACTION_NEVER: - // Looks good! - break; - - default: - // Mutually exclusive options selected! - throw new IllegalArgumentException("SHOW_AS_ACTION_ALWAYS, SHOW_AS_ACTION_IF_ROOM," - + " and SHOW_AS_ACTION_NEVER are mutually exclusive."); - } - mShowAsAction = actionEnum; - mMenu.onItemActionRequestChanged(this); - } - - public MenuItem setActionView(View view) { - mActionView = view; - mActionProvider = null; - if (view != null && view.getId() == View.NO_ID && mId > 0) { - view.setId(mId); - } - mMenu.onItemActionRequestChanged(this); - return this; - } - - public MenuItem setActionView(int resId) { - final Context context = mMenu.getContext(); - final LayoutInflater inflater = LayoutInflater.from(context); - setActionView(inflater.inflate(resId, new LinearLayout(context), false)); - return this; - } - - public View getActionView() { - if (mActionView != null) { - return mActionView; - } else if (mActionProvider != null) { - mActionView = mActionProvider.onCreateActionView(); - return mActionView; - } else { - return null; - } - } - - public ActionProvider getActionProvider() { - return mActionProvider; - } - - public MenuItem setActionProvider(ActionProvider actionProvider) { - mActionView = null; - mActionProvider = actionProvider; - mMenu.onItemsChanged(true); // Measurement can be changed - return this; - } - - @Override - public MenuItem setShowAsActionFlags(int actionEnum) { - setShowAsAction(actionEnum); - return this; - } - - @Override - public boolean expandActionView() { - if ((mShowAsAction & SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW) == 0 || mActionView == null) { - return false; - } - - if (mOnActionExpandListener == null || - mOnActionExpandListener.onMenuItemActionExpand(this)) { - return mMenu.expandItemActionView(this); - } - - return false; - } - - @Override - public boolean collapseActionView() { - if ((mShowAsAction & SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW) == 0) { - return false; - } - if (mActionView == null) { - // We're already collapsed if we have no action view. - return true; - } - - if (mOnActionExpandListener == null || - mOnActionExpandListener.onMenuItemActionCollapse(this)) { - return mMenu.collapseItemActionView(this); - } - - return false; - } - - @Override - public MenuItem setOnActionExpandListener(OnActionExpandListener listener) { - mOnActionExpandListener = listener; - return this; - } - - public boolean hasCollapsibleActionView() { - return (mShowAsAction & SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW) != 0 && mActionView != null; - } - - public void setActionViewExpanded(boolean isExpanded) { - mIsActionViewExpanded = isExpanded; - mMenu.onItemsChanged(false); - } - - public boolean isActionViewExpanded() { - return mIsActionViewExpanded; - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/MenuItemWrapper.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/MenuItemWrapper.java deleted file mode 100644 index 907a7aa04..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/MenuItemWrapper.java +++ /dev/null @@ -1,292 +0,0 @@ -package com.actionbarsherlock.internal.view.menu; - -import android.content.Intent; -import android.graphics.drawable.Drawable; -import android.view.View; -import android.view.ContextMenu.ContextMenuInfo; -import com.actionbarsherlock.internal.view.ActionProviderWrapper; -import com.actionbarsherlock.view.ActionProvider; -import com.actionbarsherlock.view.MenuItem; -import com.actionbarsherlock.view.SubMenu; - -public class MenuItemWrapper implements MenuItem, android.view.MenuItem.OnMenuItemClickListener { - private final android.view.MenuItem mNativeItem; - private SubMenu mSubMenu = null; - private OnMenuItemClickListener mMenuItemClickListener = null; - private OnActionExpandListener mActionExpandListener = null; - private android.view.MenuItem.OnActionExpandListener mNativeActionExpandListener = null; - - - public MenuItemWrapper(android.view.MenuItem nativeItem) { - if (nativeItem == null) { - throw new IllegalStateException("Wrapped menu item cannot be null."); - } - mNativeItem = nativeItem; - } - - - @Override - public int getItemId() { - return mNativeItem.getItemId(); - } - - @Override - public int getGroupId() { - return mNativeItem.getGroupId(); - } - - @Override - public int getOrder() { - return mNativeItem.getOrder(); - } - - @Override - public MenuItem setTitle(CharSequence title) { - mNativeItem.setTitle(title); - return this; - } - - @Override - public MenuItem setTitle(int title) { - mNativeItem.setTitle(title); - return this; - } - - @Override - public CharSequence getTitle() { - return mNativeItem.getTitle(); - } - - @Override - public MenuItem setTitleCondensed(CharSequence title) { - mNativeItem.setTitleCondensed(title); - return this; - } - - @Override - public CharSequence getTitleCondensed() { - return mNativeItem.getTitleCondensed(); - } - - @Override - public MenuItem setIcon(Drawable icon) { - mNativeItem.setIcon(icon); - return this; - } - - @Override - public MenuItem setIcon(int iconRes) { - mNativeItem.setIcon(iconRes); - return this; - } - - @Override - public Drawable getIcon() { - return mNativeItem.getIcon(); - } - - @Override - public MenuItem setIntent(Intent intent) { - mNativeItem.setIntent(intent); - return this; - } - - @Override - public Intent getIntent() { - return mNativeItem.getIntent(); - } - - @Override - public MenuItem setShortcut(char numericChar, char alphaChar) { - mNativeItem.setShortcut(numericChar, alphaChar); - return this; - } - - @Override - public MenuItem setNumericShortcut(char numericChar) { - mNativeItem.setNumericShortcut(numericChar); - return this; - } - - @Override - public char getNumericShortcut() { - return mNativeItem.getNumericShortcut(); - } - - @Override - public MenuItem setAlphabeticShortcut(char alphaChar) { - mNativeItem.setAlphabeticShortcut(alphaChar); - return this; - } - - @Override - public char getAlphabeticShortcut() { - return mNativeItem.getAlphabeticShortcut(); - } - - @Override - public MenuItem setCheckable(boolean checkable) { - mNativeItem.setCheckable(checkable); - return this; - } - - @Override - public boolean isCheckable() { - return mNativeItem.isCheckable(); - } - - @Override - public MenuItem setChecked(boolean checked) { - mNativeItem.setChecked(checked); - return this; - } - - @Override - public boolean isChecked() { - return mNativeItem.isChecked(); - } - - @Override - public MenuItem setVisible(boolean visible) { - mNativeItem.setVisible(visible); - return this; - } - - @Override - public boolean isVisible() { - return mNativeItem.isVisible(); - } - - @Override - public MenuItem setEnabled(boolean enabled) { - mNativeItem.setEnabled(enabled); - return this; - } - - @Override - public boolean isEnabled() { - return mNativeItem.isEnabled(); - } - - @Override - public boolean hasSubMenu() { - return mNativeItem.hasSubMenu(); - } - - @Override - public SubMenu getSubMenu() { - if (hasSubMenu() && (mSubMenu == null)) { - mSubMenu = new SubMenuWrapper(mNativeItem.getSubMenu()); - } - return mSubMenu; - } - - @Override - public MenuItem setOnMenuItemClickListener(OnMenuItemClickListener menuItemClickListener) { - mMenuItemClickListener = menuItemClickListener; - //Register ourselves as the listener to proxy - mNativeItem.setOnMenuItemClickListener(this); - return this; - } - - @Override - public boolean onMenuItemClick(android.view.MenuItem item) { - if (mMenuItemClickListener != null) { - return mMenuItemClickListener.onMenuItemClick(this); - } - return false; - } - - @Override - public ContextMenuInfo getMenuInfo() { - return mNativeItem.getMenuInfo(); - } - - @Override - public void setShowAsAction(int actionEnum) { - mNativeItem.setShowAsAction(actionEnum); - } - - @Override - public MenuItem setShowAsActionFlags(int actionEnum) { - mNativeItem.setShowAsActionFlags(actionEnum); - return this; - } - - @Override - public MenuItem setActionView(View view) { - mNativeItem.setActionView(view); - return this; - } - - @Override - public MenuItem setActionView(int resId) { - mNativeItem.setActionView(resId); - return this; - } - - @Override - public View getActionView() { - return mNativeItem.getActionView(); - } - - @Override - public MenuItem setActionProvider(ActionProvider actionProvider) { - mNativeItem.setActionProvider(new ActionProviderWrapper(actionProvider)); - return this; - } - - @Override - public ActionProvider getActionProvider() { - android.view.ActionProvider nativeProvider = mNativeItem.getActionProvider(); - if (nativeProvider != null && nativeProvider instanceof ActionProviderWrapper) { - return ((ActionProviderWrapper)nativeProvider).unwrap(); - } - return null; - } - - @Override - public boolean expandActionView() { - return mNativeItem.expandActionView(); - } - - @Override - public boolean collapseActionView() { - return mNativeItem.collapseActionView(); - } - - @Override - public boolean isActionViewExpanded() { - return mNativeItem.isActionViewExpanded(); - } - - @Override - public MenuItem setOnActionExpandListener(OnActionExpandListener listener) { - mActionExpandListener = listener; - - if (mNativeActionExpandListener == null) { - mNativeActionExpandListener = new android.view.MenuItem.OnActionExpandListener() { - @Override - public boolean onMenuItemActionExpand(android.view.MenuItem menuItem) { - if (mActionExpandListener != null) { - return mActionExpandListener.onMenuItemActionExpand(MenuItemWrapper.this); - } - return false; - } - - @Override - public boolean onMenuItemActionCollapse(android.view.MenuItem menuItem) { - if (mActionExpandListener != null) { - return mActionExpandListener.onMenuItemActionCollapse(MenuItemWrapper.this); - } - return false; - } - }; - - //Register our inner-class as the listener to proxy method calls - mNativeItem.setOnActionExpandListener(mNativeActionExpandListener); - } - - return this; - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/MenuPopupHelper.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/MenuPopupHelper.java deleted file mode 100644 index f030de310..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/MenuPopupHelper.java +++ /dev/null @@ -1,376 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.view.menu; - -import java.util.ArrayList; -import android.content.Context; -import android.content.res.Resources; -import android.database.DataSetObserver; -import android.os.Parcelable; -import android.view.KeyEvent; -import android.view.LayoutInflater; -import android.view.View; -import android.view.View.MeasureSpec; -import android.view.ViewGroup; -import android.view.ViewTreeObserver; -import android.widget.AdapterView; -import android.widget.BaseAdapter; -import android.widget.FrameLayout; -import android.widget.ListAdapter; -import android.widget.PopupWindow; -import com.actionbarsherlock.R; -import com.actionbarsherlock.internal.view.View_HasStateListenerSupport; -import com.actionbarsherlock.internal.view.View_OnAttachStateChangeListener; -import com.actionbarsherlock.internal.widget.IcsListPopupWindow; -import com.actionbarsherlock.view.MenuItem; - -/** - * Presents a menu as a small, simple popup anchored to another view. - * @hide - */ -public class MenuPopupHelper implements AdapterView.OnItemClickListener, View.OnKeyListener, - ViewTreeObserver.OnGlobalLayoutListener, PopupWindow.OnDismissListener, - View_OnAttachStateChangeListener, MenuPresenter { - //UNUSED private static final String TAG = "MenuPopupHelper"; - - static final int ITEM_LAYOUT = R.layout.abs__popup_menu_item_layout; - - private Context mContext; - private LayoutInflater mInflater; - private IcsListPopupWindow mPopup; - private MenuBuilder mMenu; - private int mPopupMaxWidth; - private View mAnchorView; - private boolean mOverflowOnly; - private ViewTreeObserver mTreeObserver; - - private MenuAdapter mAdapter; - - private Callback mPresenterCallback; - - boolean mForceShowIcon; - - private ViewGroup mMeasureParent; - - public MenuPopupHelper(Context context, MenuBuilder menu) { - this(context, menu, null, false); - } - - public MenuPopupHelper(Context context, MenuBuilder menu, View anchorView) { - this(context, menu, anchorView, false); - } - - public MenuPopupHelper(Context context, MenuBuilder menu, - View anchorView, boolean overflowOnly) { - mContext = context; - mInflater = LayoutInflater.from(context); - mMenu = menu; - mOverflowOnly = overflowOnly; - - final Resources res = context.getResources(); - mPopupMaxWidth = Math.max(res.getDisplayMetrics().widthPixels / 2, - res.getDimensionPixelSize(R.dimen.abs__config_prefDialogWidth)); - - mAnchorView = anchorView; - - menu.addMenuPresenter(this); - } - - public void setAnchorView(View anchor) { - mAnchorView = anchor; - } - - public void setForceShowIcon(boolean forceShow) { - mForceShowIcon = forceShow; - } - - public void show() { - if (!tryShow()) { - throw new IllegalStateException("MenuPopupHelper cannot be used without an anchor"); - } - } - - public boolean tryShow() { - mPopup = new IcsListPopupWindow(mContext, null, R.attr.popupMenuStyle); - mPopup.setOnDismissListener(this); - mPopup.setOnItemClickListener(this); - - mAdapter = new MenuAdapter(mMenu); - mPopup.setAdapter(mAdapter); - mPopup.setModal(true); - - View anchor = mAnchorView; - if (anchor != null) { - final boolean addGlobalListener = mTreeObserver == null; - mTreeObserver = anchor.getViewTreeObserver(); // Refresh to latest - if (addGlobalListener) mTreeObserver.addOnGlobalLayoutListener(this); - ((View_HasStateListenerSupport)anchor).addOnAttachStateChangeListener(this); - mPopup.setAnchorView(anchor); - } else { - return false; - } - - mPopup.setContentWidth(Math.min(measureContentWidth(mAdapter), mPopupMaxWidth)); - mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED); - mPopup.show(); - mPopup.getListView().setOnKeyListener(this); - return true; - } - - public void dismiss() { - if (isShowing()) { - mPopup.dismiss(); - } - } - - public void onDismiss() { - mPopup = null; - mMenu.close(); - if (mTreeObserver != null) { - if (!mTreeObserver.isAlive()) mTreeObserver = mAnchorView.getViewTreeObserver(); - mTreeObserver.removeGlobalOnLayoutListener(this); - mTreeObserver = null; - } - ((View_HasStateListenerSupport)mAnchorView).removeOnAttachStateChangeListener(this); - } - - public boolean isShowing() { - return mPopup != null && mPopup.isShowing(); - } - - @Override - public void onItemClick(AdapterView parent, View view, int position, long id) { - MenuAdapter adapter = mAdapter; - adapter.mAdapterMenu.performItemAction(adapter.getItem(position), 0); - } - - public boolean onKey(View v, int keyCode, KeyEvent event) { - if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_MENU) { - dismiss(); - return true; - } - return false; - } - - private int measureContentWidth(ListAdapter adapter) { - // Menus don't tend to be long, so this is more sane than it looks. - int width = 0; - View itemView = null; - int itemType = 0; - final int widthMeasureSpec = - MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); - final int heightMeasureSpec = - MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); - final int count = adapter.getCount(); - for (int i = 0; i < count; i++) { - final int positionType = adapter.getItemViewType(i); - if (positionType != itemType) { - itemType = positionType; - itemView = null; - } - if (mMeasureParent == null) { - mMeasureParent = new FrameLayout(mContext); - } - itemView = adapter.getView(i, itemView, mMeasureParent); - itemView.measure(widthMeasureSpec, heightMeasureSpec); - width = Math.max(width, itemView.getMeasuredWidth()); - } - return width; - } - - @Override - public void onGlobalLayout() { - if (isShowing()) { - final View anchor = mAnchorView; - if (anchor == null || !anchor.isShown()) { - dismiss(); - } else if (isShowing()) { - // Recompute window size and position - mPopup.show(); - } - } - } - - @Override - public void onViewAttachedToWindow(View v) { - } - - @Override - public void onViewDetachedFromWindow(View v) { - if (mTreeObserver != null) { - if (!mTreeObserver.isAlive()) mTreeObserver = v.getViewTreeObserver(); - mTreeObserver.removeGlobalOnLayoutListener(this); - } - ((View_HasStateListenerSupport)v).removeOnAttachStateChangeListener(this); - } - - @Override - public void initForMenu(Context context, MenuBuilder menu) { - // Don't need to do anything; we added as a presenter in the constructor. - } - - @Override - public MenuView getMenuView(ViewGroup root) { - throw new UnsupportedOperationException("MenuPopupHelpers manage their own views"); - } - - @Override - public void updateMenuView(boolean cleared) { - if (mAdapter != null) mAdapter.notifyDataSetChanged(); - } - - @Override - public void setCallback(Callback cb) { - mPresenterCallback = cb; - } - - @Override - public boolean onSubMenuSelected(SubMenuBuilder subMenu) { - if (subMenu.hasVisibleItems()) { - MenuPopupHelper subPopup = new MenuPopupHelper(mContext, subMenu, mAnchorView, false); - subPopup.setCallback(mPresenterCallback); - - boolean preserveIconSpacing = false; - final int count = subMenu.size(); - for (int i = 0; i < count; i++) { - MenuItem childItem = subMenu.getItem(i); - if (childItem.isVisible() && childItem.getIcon() != null) { - preserveIconSpacing = true; - break; - } - } - subPopup.setForceShowIcon(preserveIconSpacing); - - if (subPopup.tryShow()) { - if (mPresenterCallback != null) { - mPresenterCallback.onOpenSubMenu(subMenu); - } - return true; - } - } - return false; - } - - @Override - public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) { - // Only care about the (sub)menu we're presenting. - if (menu != mMenu) return; - - dismiss(); - if (mPresenterCallback != null) { - mPresenterCallback.onCloseMenu(menu, allMenusAreClosing); - } - } - - @Override - public boolean flagActionItems() { - return false; - } - - public boolean expandItemActionView(MenuBuilder menu, MenuItemImpl item) { - return false; - } - - public boolean collapseItemActionView(MenuBuilder menu, MenuItemImpl item) { - return false; - } - - @Override - public int getId() { - return 0; - } - - @Override - public Parcelable onSaveInstanceState() { - return null; - } - - @Override - public void onRestoreInstanceState(Parcelable state) { - } - - private class MenuAdapter extends BaseAdapter { - private MenuBuilder mAdapterMenu; - private int mExpandedIndex = -1; - - public MenuAdapter(MenuBuilder menu) { - mAdapterMenu = menu; - registerDataSetObserver(new ExpandedIndexObserver()); - findExpandedIndex(); - } - - public int getCount() { - ArrayList items = mOverflowOnly ? - mAdapterMenu.getNonActionItems() : mAdapterMenu.getVisibleItems(); - if (mExpandedIndex < 0) { - return items.size(); - } - return items.size() - 1; - } - - public MenuItemImpl getItem(int position) { - ArrayList items = mOverflowOnly ? - mAdapterMenu.getNonActionItems() : mAdapterMenu.getVisibleItems(); - if (mExpandedIndex >= 0 && position >= mExpandedIndex) { - position++; - } - return items.get(position); - } - - public long getItemId(int position) { - // Since a menu item's ID is optional, we'll use the position as an - // ID for the item in the AdapterView - return position; - } - - public View getView(int position, View convertView, ViewGroup parent) { - if (convertView == null) { - convertView = mInflater.inflate(ITEM_LAYOUT, parent, false); - } - - MenuView.ItemView itemView = (MenuView.ItemView) convertView; - if (mForceShowIcon) { - ((ListMenuItemView) convertView).setForceShowIcon(true); - } - itemView.initialize(getItem(position), 0); - return convertView; - } - - void findExpandedIndex() { - final MenuItemImpl expandedItem = mMenu.getExpandedItem(); - if (expandedItem != null) { - final ArrayList items = mMenu.getNonActionItems(); - final int count = items.size(); - for (int i = 0; i < count; i++) { - final MenuItemImpl item = items.get(i); - if (item == expandedItem) { - mExpandedIndex = i; - return; - } - } - } - mExpandedIndex = -1; - } - } - - private class ExpandedIndexObserver extends DataSetObserver { - @Override - public void onChanged() { - mAdapter.findExpandedIndex(); - } - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/MenuPresenter.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/MenuPresenter.java deleted file mode 100644 index c3f35472c..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/MenuPresenter.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.view.menu; - -import android.content.Context; -import android.os.Parcelable; -import android.view.ViewGroup; - -/** - * A MenuPresenter is responsible for building views for a Menu object. - * It takes over some responsibility from the old style monolithic MenuBuilder class. - */ -public interface MenuPresenter { - /** - * Called by menu implementation to notify another component of open/close events. - */ - public interface Callback { - /** - * Called when a menu is closing. - * @param menu - * @param allMenusAreClosing - */ - public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing); - - /** - * Called when a submenu opens. Useful for notifying the application - * of menu state so that it does not attempt to hide the action bar - * while a submenu is open or similar. - * - * @param subMenu Submenu currently being opened - * @return true if the Callback will handle presenting the submenu, false if - * the presenter should attempt to do so. - */ - public boolean onOpenSubMenu(MenuBuilder subMenu); - } - - /** - * Initialize this presenter for the given context and menu. - * This method is called by MenuBuilder when a presenter is - * added. See {@link MenuBuilder#addMenuPresenter(MenuPresenter)} - * - * @param context Context for this presenter; used for view creation and resource management - * @param menu Menu to host - */ - public void initForMenu(Context context, MenuBuilder menu); - - /** - * Retrieve a MenuView to display the menu specified in - * {@link #initForMenu(Context, Menu)}. - * - * @param root Intended parent of the MenuView. - * @return A freshly created MenuView. - */ - public MenuView getMenuView(ViewGroup root); - - /** - * Update the menu UI in response to a change. Called by - * MenuBuilder during the normal course of operation. - * - * @param cleared true if the menu was entirely cleared - */ - public void updateMenuView(boolean cleared); - - /** - * Set a callback object that will be notified of menu events - * related to this specific presentation. - * @param cb Callback that will be notified of future events - */ - public void setCallback(Callback cb); - - /** - * Called by Menu implementations to indicate that a submenu item - * has been selected. An active Callback should be notified, and - * if applicable the presenter should present the submenu. - * - * @param subMenu SubMenu being opened - * @return true if the the event was handled, false otherwise. - */ - public boolean onSubMenuSelected(SubMenuBuilder subMenu); - - /** - * Called by Menu implementations to indicate that a menu or submenu is - * closing. Presenter implementations should close the representation - * of the menu indicated as necessary and notify a registered callback. - * - * @param menu Menu or submenu that is closing. - * @param allMenusAreClosing True if all associated menus are closing. - */ - public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing); - - /** - * Called by Menu implementations to flag items that will be shown as actions. - * @return true if this presenter changed the action status of any items. - */ - public boolean flagActionItems(); - - /** - * Called when a menu item with a collapsable action view should expand its action view. - * - * @param menu Menu containing the item to be expanded - * @param item Item to be expanded - * @return true if this presenter expanded the action view, false otherwise. - */ - public boolean expandItemActionView(MenuBuilder menu, MenuItemImpl item); - - /** - * Called when a menu item with a collapsable action view should collapse its action view. - * - * @param menu Menu containing the item to be collapsed - * @param item Item to be collapsed - * @return true if this presenter collapsed the action view, false otherwise. - */ - public boolean collapseItemActionView(MenuBuilder menu, MenuItemImpl item); - - /** - * Returns an ID for determining how to save/restore instance state. - * @return a valid ID value. - */ - public int getId(); - - /** - * Returns a Parcelable describing the current state of the presenter. - * It will be passed to the {@link #onRestoreInstanceState(Parcelable)} - * method of the presenter sharing the same ID later. - * @return The saved instance state - */ - public Parcelable onSaveInstanceState(); - - /** - * Supplies the previously saved instance state to be restored. - * @param state The previously saved instance state - */ - public void onRestoreInstanceState(Parcelable state); -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/MenuView.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/MenuView.java deleted file mode 100644 index 323ba2d88..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/MenuView.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.view.menu; - -import android.graphics.drawable.Drawable; - -/** - * Minimal interface for a menu view. {@link #initialize(MenuBuilder)} must be called for the - * menu to be functional. - * - * @hide - */ -public interface MenuView { - /** - * Initializes the menu to the given menu. This should be called after the - * view is inflated. - * - * @param menu The menu that this MenuView should display. - */ - public void initialize(MenuBuilder menu); - - /** - * Returns the default animations to be used for this menu when entering/exiting. - * @return A resource ID for the default animations to be used for this menu. - */ - public int getWindowAnimations(); - - /** - * Minimal interface for a menu item view. {@link #initialize(MenuItemImpl, int)} must be called - * for the item to be functional. - */ - public interface ItemView { - /** - * Initializes with the provided MenuItemData. This should be called after the view is - * inflated. - * @param itemData The item that this ItemView should display. - * @param menuType The type of this menu, one of - * {@link MenuBuilder#TYPE_ICON}, {@link MenuBuilder#TYPE_EXPANDED}, - * {@link MenuBuilder#TYPE_DIALOG}). - */ - public void initialize(MenuItemImpl itemData, int menuType); - - /** - * Gets the item data that this view is displaying. - * @return the item data, or null if there is not one - */ - public MenuItemImpl getItemData(); - - /** - * Sets the title of the item view. - * @param title The title to set. - */ - public void setTitle(CharSequence title); - - /** - * Sets the enabled state of the item view. - * @param enabled Whether the item view should be enabled. - */ - public void setEnabled(boolean enabled); - - /** - * Displays the checkbox for the item view. This does not ensure the item view will be - * checked, for that use {@link #setChecked}. - * @param checkable Whether to display the checkbox or to hide it - */ - public void setCheckable(boolean checkable); - - /** - * Checks the checkbox for the item view. If the checkbox is hidden, it will NOT be - * made visible, call {@link #setCheckable(boolean)} for that. - * @param checked Whether the checkbox should be checked - */ - public void setChecked(boolean checked); - - /** - * Sets the shortcut for the item. - * @param showShortcut Whether a shortcut should be shown(if false, the value of - * shortcutKey should be ignored). - * @param shortcutKey The shortcut key that should be shown on the ItemView. - */ - public void setShortcut(boolean showShortcut, char shortcutKey); - - /** - * Set the icon of this item view. - * @param icon The icon of this item. null to hide the icon. - */ - public void setIcon(Drawable icon); - - /** - * Whether this item view prefers displaying the condensed title rather - * than the normal title. If a condensed title is not available, the - * normal title will be used. - * - * @return Whether this item view prefers displaying the condensed - * title. - */ - public boolean prefersCondensedTitle(); - - /** - * Whether this item view shows an icon. - * - * @return Whether this item view shows an icon. - */ - public boolean showsIcon(); - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/MenuWrapper.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/MenuWrapper.java deleted file mode 100644 index 64fc4aeaa..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/MenuWrapper.java +++ /dev/null @@ -1,180 +0,0 @@ -package com.actionbarsherlock.internal.view.menu; - -import java.util.WeakHashMap; -import android.content.ComponentName; -import android.content.Intent; -import android.view.KeyEvent; -import com.actionbarsherlock.view.Menu; -import com.actionbarsherlock.view.MenuItem; -import com.actionbarsherlock.view.SubMenu; - -public class MenuWrapper implements Menu { - private final android.view.Menu mNativeMenu; - - private final WeakHashMap mNativeMap = - new WeakHashMap(); - - - public MenuWrapper(android.view.Menu nativeMenu) { - mNativeMenu = nativeMenu; - } - - public android.view.Menu unwrap() { - return mNativeMenu; - } - - private MenuItem addInternal(android.view.MenuItem nativeItem) { - MenuItem item = new MenuItemWrapper(nativeItem); - mNativeMap.put(nativeItem, item); - return item; - } - - @Override - public MenuItem add(CharSequence title) { - return addInternal(mNativeMenu.add(title)); - } - - @Override - public MenuItem add(int titleRes) { - return addInternal(mNativeMenu.add(titleRes)); - } - - @Override - public MenuItem add(int groupId, int itemId, int order, CharSequence title) { - return addInternal(mNativeMenu.add(groupId, itemId, order, title)); - } - - @Override - public MenuItem add(int groupId, int itemId, int order, int titleRes) { - return addInternal(mNativeMenu.add(groupId, itemId, order, titleRes)); - } - - private SubMenu addInternal(android.view.SubMenu nativeSubMenu) { - SubMenu subMenu = new SubMenuWrapper(nativeSubMenu); - android.view.MenuItem nativeItem = nativeSubMenu.getItem(); - MenuItem item = subMenu.getItem(); - mNativeMap.put(nativeItem, item); - return subMenu; - } - - @Override - public SubMenu addSubMenu(CharSequence title) { - return addInternal(mNativeMenu.addSubMenu(title)); - } - - @Override - public SubMenu addSubMenu(int titleRes) { - return addInternal(mNativeMenu.addSubMenu(titleRes)); - } - - @Override - public SubMenu addSubMenu(int groupId, int itemId, int order, CharSequence title) { - return addInternal(mNativeMenu.addSubMenu(groupId, itemId, order, title)); - } - - @Override - public SubMenu addSubMenu(int groupId, int itemId, int order, int titleRes) { - return addInternal(mNativeMenu.addSubMenu(groupId, itemId, order, titleRes)); - } - - @Override - public int addIntentOptions(int groupId, int itemId, int order, ComponentName caller, Intent[] specifics, Intent intent, int flags, MenuItem[] outSpecificItems) { - android.view.MenuItem[] nativeOutItems = new android.view.MenuItem[outSpecificItems.length]; - int result = mNativeMenu.addIntentOptions(groupId, itemId, order, caller, specifics, intent, flags, nativeOutItems); - for (int i = 0, length = outSpecificItems.length; i < length; i++) { - outSpecificItems[i] = new MenuItemWrapper(nativeOutItems[i]); - } - return result; - } - - @Override - public void removeItem(int id) { - mNativeMenu.removeItem(id); - } - - @Override - public void removeGroup(int groupId) { - mNativeMenu.removeGroup(groupId); - } - - @Override - public void clear() { - mNativeMap.clear(); - mNativeMenu.clear(); - } - - @Override - public void setGroupCheckable(int group, boolean checkable, boolean exclusive) { - mNativeMenu.setGroupCheckable(group, checkable, exclusive); - } - - @Override - public void setGroupVisible(int group, boolean visible) { - mNativeMenu.setGroupVisible(group, visible); - } - - @Override - public void setGroupEnabled(int group, boolean enabled) { - mNativeMenu.setGroupEnabled(group, enabled); - } - - @Override - public boolean hasVisibleItems() { - return mNativeMenu.hasVisibleItems(); - } - - @Override - public MenuItem findItem(int id) { - android.view.MenuItem nativeItem = mNativeMenu.findItem(id); - return findItem(nativeItem); - } - - public MenuItem findItem(android.view.MenuItem nativeItem) { - if (nativeItem == null) { - return null; - } - - MenuItem wrapped = mNativeMap.get(nativeItem); - if (wrapped != null) { - return wrapped; - } - - return addInternal(nativeItem); - } - - @Override - public int size() { - return mNativeMenu.size(); - } - - @Override - public MenuItem getItem(int index) { - android.view.MenuItem nativeItem = mNativeMenu.getItem(index); - return findItem(nativeItem); - } - - @Override - public void close() { - mNativeMenu.close(); - } - - @Override - public boolean performShortcut(int keyCode, KeyEvent event, int flags) { - return mNativeMenu.performShortcut(keyCode, event, flags); - } - - @Override - public boolean isShortcutKey(int keyCode, KeyEvent event) { - return mNativeMenu.isShortcutKey(keyCode, event); - } - - @Override - public boolean performIdentifierAction(int id, int flags) { - return mNativeMenu.performIdentifierAction(id, flags); - } - - @Override - public void setQwertyMode(boolean isQwerty) { - mNativeMenu.setQwertyMode(isQwerty); - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/SubMenuBuilder.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/SubMenuBuilder.java deleted file mode 100644 index 6679cf386..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/SubMenuBuilder.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.view.menu; - -import android.content.Context; -import android.graphics.drawable.Drawable; -import android.view.View; - -import com.actionbarsherlock.view.Menu; -import com.actionbarsherlock.view.MenuItem; -import com.actionbarsherlock.view.SubMenu; - -/** - * The model for a sub menu, which is an extension of the menu. Most methods are proxied to - * the parent menu. - */ -public class SubMenuBuilder extends MenuBuilder implements SubMenu { - private MenuBuilder mParentMenu; - private MenuItemImpl mItem; - - public SubMenuBuilder(Context context, MenuBuilder parentMenu, MenuItemImpl item) { - super(context); - - mParentMenu = parentMenu; - mItem = item; - } - - @Override - public void setQwertyMode(boolean isQwerty) { - mParentMenu.setQwertyMode(isQwerty); - } - - @Override - public boolean isQwertyMode() { - return mParentMenu.isQwertyMode(); - } - - @Override - public void setShortcutsVisible(boolean shortcutsVisible) { - mParentMenu.setShortcutsVisible(shortcutsVisible); - } - - @Override - public boolean isShortcutsVisible() { - return mParentMenu.isShortcutsVisible(); - } - - public Menu getParentMenu() { - return mParentMenu; - } - - public MenuItem getItem() { - return mItem; - } - - @Override - public void setCallback(Callback callback) { - mParentMenu.setCallback(callback); - } - - @Override - public MenuBuilder getRootMenu() { - return mParentMenu; - } - - @Override - boolean dispatchMenuItemSelected(MenuBuilder menu, MenuItem item) { - return super.dispatchMenuItemSelected(menu, item) || - mParentMenu.dispatchMenuItemSelected(menu, item); - } - - public SubMenu setIcon(Drawable icon) { - mItem.setIcon(icon); - return this; - } - - public SubMenu setIcon(int iconRes) { - mItem.setIcon(iconRes); - return this; - } - - public SubMenu setHeaderIcon(Drawable icon) { - return (SubMenu) super.setHeaderIconInt(icon); - } - - public SubMenu setHeaderIcon(int iconRes) { - return (SubMenu) super.setHeaderIconInt(iconRes); - } - - public SubMenu setHeaderTitle(CharSequence title) { - return (SubMenu) super.setHeaderTitleInt(title); - } - - public SubMenu setHeaderTitle(int titleRes) { - return (SubMenu) super.setHeaderTitleInt(titleRes); - } - - public SubMenu setHeaderView(View view) { - return (SubMenu) super.setHeaderViewInt(view); - } - - @Override - public boolean expandItemActionView(MenuItemImpl item) { - return mParentMenu.expandItemActionView(item); - } - - @Override - public boolean collapseItemActionView(MenuItemImpl item) { - return mParentMenu.collapseItemActionView(item); - } - - @Override - public String getActionViewStatesKey() { - final int itemId = mItem != null ? mItem.getItemId() : 0; - if (itemId == 0) { - return null; - } - return super.getActionViewStatesKey() + ":" + itemId; - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/SubMenuWrapper.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/SubMenuWrapper.java deleted file mode 100644 index 7d307acb1..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/SubMenuWrapper.java +++ /dev/null @@ -1,72 +0,0 @@ -package com.actionbarsherlock.internal.view.menu; - -import android.graphics.drawable.Drawable; -import android.view.View; -import com.actionbarsherlock.view.MenuItem; -import com.actionbarsherlock.view.SubMenu; - -public class SubMenuWrapper extends MenuWrapper implements SubMenu { - private final android.view.SubMenu mNativeSubMenu; - private MenuItem mItem = null; - - public SubMenuWrapper(android.view.SubMenu nativeSubMenu) { - super(nativeSubMenu); - mNativeSubMenu = nativeSubMenu; - } - - - @Override - public SubMenu setHeaderTitle(int titleRes) { - mNativeSubMenu.setHeaderTitle(titleRes); - return this; - } - - @Override - public SubMenu setHeaderTitle(CharSequence title) { - mNativeSubMenu.setHeaderTitle(title); - return this; - } - - @Override - public SubMenu setHeaderIcon(int iconRes) { - mNativeSubMenu.setHeaderIcon(iconRes); - return this; - } - - @Override - public SubMenu setHeaderIcon(Drawable icon) { - mNativeSubMenu.setHeaderIcon(icon); - return this; - } - - @Override - public SubMenu setHeaderView(View view) { - mNativeSubMenu.setHeaderView(view); - return this; - } - - @Override - public void clearHeader() { - mNativeSubMenu.clearHeader(); - } - - @Override - public SubMenu setIcon(int iconRes) { - mNativeSubMenu.setIcon(iconRes); - return this; - } - - @Override - public SubMenu setIcon(Drawable icon) { - mNativeSubMenu.setIcon(icon); - return this; - } - - @Override - public MenuItem getItem() { - if (mItem == null) { - mItem = new MenuItemWrapper(mNativeSubMenu.getItem()); - } - return mItem; - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/AbsActionBarView.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/AbsActionBarView.java deleted file mode 100644 index 3a4a44675..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/AbsActionBarView.java +++ /dev/null @@ -1,291 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.actionbarsherlock.internal.widget; - -import android.content.Context; -import android.content.res.Configuration; -import android.content.res.TypedArray; -import android.os.Build; -import android.util.AttributeSet; -import android.view.View; -import android.view.animation.DecelerateInterpolator; -import android.view.animation.Interpolator; - -import com.actionbarsherlock.R; -import com.actionbarsherlock.internal.nineoldandroids.animation.Animator; -import com.actionbarsherlock.internal.nineoldandroids.animation.AnimatorSet; -import com.actionbarsherlock.internal.nineoldandroids.animation.ObjectAnimator; -import com.actionbarsherlock.internal.nineoldandroids.view.NineViewGroup; -import com.actionbarsherlock.internal.view.menu.ActionMenuPresenter; -import com.actionbarsherlock.internal.view.menu.ActionMenuView; - -import static com.actionbarsherlock.internal.ResourcesCompat.getResources_getBoolean; - -public abstract class AbsActionBarView extends NineViewGroup { - protected ActionMenuView mMenuView; - protected ActionMenuPresenter mActionMenuPresenter; - protected ActionBarContainer mSplitView; - protected boolean mSplitActionBar; - protected boolean mSplitWhenNarrow; - protected int mContentHeight; - - final Context mContext; - - protected Animator mVisibilityAnim; - protected final VisibilityAnimListener mVisAnimListener = new VisibilityAnimListener(); - - private static final /*Time*/Interpolator sAlphaInterpolator = new DecelerateInterpolator(); - - private static final int FADE_DURATION = 200; - - public AbsActionBarView(Context context) { - super(context); - mContext = context; - } - - public AbsActionBarView(Context context, AttributeSet attrs) { - super(context, attrs); - mContext = context; - } - - public AbsActionBarView(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - mContext = context; - } - - /* - * Must be public so we can dispatch pre-2.2 via ActionBarImpl. - */ - @Override - public void onConfigurationChanged(Configuration newConfig) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) { - super.onConfigurationChanged(newConfig); - } else if (mMenuView != null) { - mMenuView.onConfigurationChanged(newConfig); - } - - // Action bar can change size on configuration changes. - // Reread the desired height from the theme-specified style. - TypedArray a = getContext().obtainStyledAttributes(null, R.styleable.SherlockActionBar, - R.attr.actionBarStyle, 0); - setContentHeight(a.getLayoutDimension(R.styleable.SherlockActionBar_height, 0)); - a.recycle(); - if (mSplitWhenNarrow) { - setSplitActionBar(getResources_getBoolean(getContext(), - R.bool.abs__split_action_bar_is_narrow)); - } - if (mActionMenuPresenter != null) { - mActionMenuPresenter.onConfigurationChanged(newConfig); - } - } - - /** - * Sets whether the bar should be split right now, no questions asked. - * @param split true if the bar should split - */ - public void setSplitActionBar(boolean split) { - mSplitActionBar = split; - } - - /** - * Sets whether the bar should split if we enter a narrow screen configuration. - * @param splitWhenNarrow true if the bar should check to split after a config change - */ - public void setSplitWhenNarrow(boolean splitWhenNarrow) { - mSplitWhenNarrow = splitWhenNarrow; - } - - public void setContentHeight(int height) { - mContentHeight = height; - requestLayout(); - } - - public int getContentHeight() { - return mContentHeight; - } - - public void setSplitView(ActionBarContainer splitView) { - mSplitView = splitView; - } - - /** - * @return Current visibility or if animating, the visibility being animated to. - */ - public int getAnimatedVisibility() { - if (mVisibilityAnim != null) { - return mVisAnimListener.mFinalVisibility; - } - return getVisibility(); - } - - public void animateToVisibility(int visibility) { - if (mVisibilityAnim != null) { - mVisibilityAnim.cancel(); - } - if (visibility == VISIBLE) { - if (getVisibility() != VISIBLE) { - setAlpha(0); - if (mSplitView != null && mMenuView != null) { - mMenuView.setAlpha(0); - } - } - ObjectAnimator anim = ObjectAnimator.ofFloat(this, "alpha", 1); - anim.setDuration(FADE_DURATION); - anim.setInterpolator(sAlphaInterpolator); - if (mSplitView != null && mMenuView != null) { - AnimatorSet set = new AnimatorSet(); - ObjectAnimator splitAnim = ObjectAnimator.ofFloat(mMenuView, "alpha", 1); - splitAnim.setDuration(FADE_DURATION); - set.addListener(mVisAnimListener.withFinalVisibility(visibility)); - set.play(anim).with(splitAnim); - set.start(); - } else { - anim.addListener(mVisAnimListener.withFinalVisibility(visibility)); - anim.start(); - } - } else { - ObjectAnimator anim = ObjectAnimator.ofFloat(this, "alpha", 0); - anim.setDuration(FADE_DURATION); - anim.setInterpolator(sAlphaInterpolator); - if (mSplitView != null && mMenuView != null) { - AnimatorSet set = new AnimatorSet(); - ObjectAnimator splitAnim = ObjectAnimator.ofFloat(mMenuView, "alpha", 0); - splitAnim.setDuration(FADE_DURATION); - set.addListener(mVisAnimListener.withFinalVisibility(visibility)); - set.play(anim).with(splitAnim); - set.start(); - } else { - anim.addListener(mVisAnimListener.withFinalVisibility(visibility)); - anim.start(); - } - } - } - - @Override - public void setVisibility(int visibility) { - if (mVisibilityAnim != null) { - mVisibilityAnim.end(); - } - super.setVisibility(visibility); - } - - public boolean showOverflowMenu() { - if (mActionMenuPresenter != null) { - return mActionMenuPresenter.showOverflowMenu(); - } - return false; - } - - public void postShowOverflowMenu() { - post(new Runnable() { - public void run() { - showOverflowMenu(); - } - }); - } - - public boolean hideOverflowMenu() { - if (mActionMenuPresenter != null) { - return mActionMenuPresenter.hideOverflowMenu(); - } - return false; - } - - public boolean isOverflowMenuShowing() { - if (mActionMenuPresenter != null) { - return mActionMenuPresenter.isOverflowMenuShowing(); - } - return false; - } - - public boolean isOverflowReserved() { - return mActionMenuPresenter != null && mActionMenuPresenter.isOverflowReserved(); - } - - public void dismissPopupMenus() { - if (mActionMenuPresenter != null) { - mActionMenuPresenter.dismissPopupMenus(); - } - } - - protected int measureChildView(View child, int availableWidth, int childSpecHeight, - int spacing) { - child.measure(MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST), - childSpecHeight); - - availableWidth -= child.getMeasuredWidth(); - availableWidth -= spacing; - - return Math.max(0, availableWidth); - } - - protected int positionChild(View child, int x, int y, int contentHeight) { - int childWidth = child.getMeasuredWidth(); - int childHeight = child.getMeasuredHeight(); - int childTop = y + (contentHeight - childHeight) / 2; - - child.layout(x, childTop, x + childWidth, childTop + childHeight); - - return childWidth; - } - - protected int positionChildInverse(View child, int x, int y, int contentHeight) { - int childWidth = child.getMeasuredWidth(); - int childHeight = child.getMeasuredHeight(); - int childTop = y + (contentHeight - childHeight) / 2; - - child.layout(x - childWidth, childTop, x, childTop + childHeight); - - return childWidth; - } - - protected class VisibilityAnimListener implements Animator.AnimatorListener { - private boolean mCanceled = false; - int mFinalVisibility; - - public VisibilityAnimListener withFinalVisibility(int visibility) { - mFinalVisibility = visibility; - return this; - } - - @Override - public void onAnimationStart(Animator animation) { - setVisibility(VISIBLE); - mVisibilityAnim = animation; - mCanceled = false; - } - - @Override - public void onAnimationEnd(Animator animation) { - if (mCanceled) return; - - mVisibilityAnim = null; - setVisibility(mFinalVisibility); - if (mSplitView != null && mMenuView != null) { - mMenuView.setVisibility(mFinalVisibility); - } - } - - @Override - public void onAnimationCancel(Animator animation) { - mCanceled = true; - } - - @Override - public void onAnimationRepeat(Animator animation) { - } - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/ActionBarContainer.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/ActionBarContainer.java deleted file mode 100644 index 5e5aa2867..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/ActionBarContainer.java +++ /dev/null @@ -1,245 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.widget; - -import android.content.Context; -import android.content.res.TypedArray; -import android.graphics.Canvas; -import android.graphics.drawable.Drawable; -import android.util.AttributeSet; -import android.view.MotionEvent; -import android.view.View; -import android.view.ViewGroup; - -import com.actionbarsherlock.R; -import com.actionbarsherlock.app.ActionBar; -import com.actionbarsherlock.internal.nineoldandroids.widget.NineFrameLayout; - -/** - * This class acts as a container for the action bar view and action mode context views. - * It applies special styles as needed to help handle animated transitions between them. - * @hide - */ -public class ActionBarContainer extends NineFrameLayout { - private boolean mIsTransitioning; - private View mTabContainer; - private ActionBarView mActionBarView; - - private Drawable mBackground; - private Drawable mStackedBackground; - private Drawable mSplitBackground; - private boolean mIsSplit; - private boolean mIsStacked; - - public ActionBarContainer(Context context) { - this(context, null); - } - - public ActionBarContainer(Context context, AttributeSet attrs) { - super(context, attrs); - - setBackgroundDrawable(null); - - TypedArray a = context.obtainStyledAttributes(attrs, - R.styleable.SherlockActionBar); - mBackground = a.getDrawable(R.styleable.SherlockActionBar_background); - mStackedBackground = a.getDrawable( - R.styleable.SherlockActionBar_backgroundStacked); - - if (getId() == R.id.abs__split_action_bar) { - mIsSplit = true; - mSplitBackground = a.getDrawable( - R.styleable.SherlockActionBar_backgroundSplit); - } - a.recycle(); - - setWillNotDraw(mIsSplit ? mSplitBackground == null : - mBackground == null && mStackedBackground == null); - } - - @Override - public void onFinishInflate() { - super.onFinishInflate(); - mActionBarView = (ActionBarView) findViewById(R.id.abs__action_bar); - } - - public void setPrimaryBackground(Drawable bg) { - mBackground = bg; - invalidate(); - } - - public void setStackedBackground(Drawable bg) { - mStackedBackground = bg; - invalidate(); - } - - public void setSplitBackground(Drawable bg) { - mSplitBackground = bg; - invalidate(); - } - - /** - * Set the action bar into a "transitioning" state. While transitioning - * the bar will block focus and touch from all of its descendants. This - * prevents the user from interacting with the bar while it is animating - * in or out. - * - * @param isTransitioning true if the bar is currently transitioning, false otherwise. - */ - public void setTransitioning(boolean isTransitioning) { - mIsTransitioning = isTransitioning; - setDescendantFocusability(isTransitioning ? FOCUS_BLOCK_DESCENDANTS - : FOCUS_AFTER_DESCENDANTS); - } - - @Override - public boolean onInterceptTouchEvent(MotionEvent ev) { - return mIsTransitioning || super.onInterceptTouchEvent(ev); - } - - @Override - public boolean onTouchEvent(MotionEvent ev) { - super.onTouchEvent(ev); - - // An action bar always eats touch events. - return true; - } - - @Override - public boolean onHoverEvent(MotionEvent ev) { - super.onHoverEvent(ev); - - // An action bar always eats hover events. - return true; - } - - public void setTabContainer(ScrollingTabContainerView tabView) { - if (mTabContainer != null) { - removeView(mTabContainer); - } - mTabContainer = tabView; - if (tabView != null) { - addView(tabView); - final ViewGroup.LayoutParams lp = tabView.getLayoutParams(); - lp.width = LayoutParams.MATCH_PARENT; - lp.height = LayoutParams.WRAP_CONTENT; - tabView.setAllowCollapse(false); - } - } - - public View getTabContainer() { - return mTabContainer; - } - - @Override - public void onDraw(Canvas canvas) { - if (getWidth() == 0 || getHeight() == 0) { - return; - } - - if (mIsSplit) { - if (mSplitBackground != null) mSplitBackground.draw(canvas); - } else { - if (mBackground != null) { - mBackground.draw(canvas); - } - if (mStackedBackground != null && mIsStacked) { - mStackedBackground.draw(canvas); - } - } - } - - //This causes the animation reflection to fail on pre-HC platforms - //@Override - //public android.view.ActionMode startActionModeForChild(View child, android.view.ActionMode.Callback callback) { - // // No starting an action mode for an action bar child! (Where would it go?) - // return null; - //} - - @Override - public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - - if (mActionBarView == null) return; - - final LayoutParams lp = (LayoutParams) mActionBarView.getLayoutParams(); - final int actionBarViewHeight = mActionBarView.isCollapsed() ? 0 : - mActionBarView.getMeasuredHeight() + lp.topMargin + lp.bottomMargin; - - if (mTabContainer != null && mTabContainer.getVisibility() != GONE) { - final int mode = MeasureSpec.getMode(heightMeasureSpec); - if (mode == MeasureSpec.AT_MOST) { - final int maxHeight = MeasureSpec.getSize(heightMeasureSpec); - setMeasuredDimension(getMeasuredWidth(), - Math.min(actionBarViewHeight + mTabContainer.getMeasuredHeight(), - maxHeight)); - } - } - } - - @Override - public void onLayout(boolean changed, int l, int t, int r, int b) { - super.onLayout(changed, l, t, r, b); - - final boolean hasTabs = mTabContainer != null && mTabContainer.getVisibility() != GONE; - - if (mTabContainer != null && mTabContainer.getVisibility() != GONE) { - final int containerHeight = getMeasuredHeight(); - final int tabHeight = mTabContainer.getMeasuredHeight(); - - if ((mActionBarView.getDisplayOptions() & ActionBar.DISPLAY_SHOW_HOME) == 0) { - // Not showing home, put tabs on top. - final int count = getChildCount(); - for (int i = 0; i < count; i++) { - final View child = getChildAt(i); - - if (child == mTabContainer) continue; - - if (!mActionBarView.isCollapsed()) { - child.offsetTopAndBottom(tabHeight); - } - } - mTabContainer.layout(l, 0, r, tabHeight); - } else { - mTabContainer.layout(l, containerHeight - tabHeight, r, containerHeight); - } - } - - boolean needsInvalidate = false; - if (mIsSplit) { - if (mSplitBackground != null) { - mSplitBackground.setBounds(0, 0, getMeasuredWidth(), getMeasuredHeight()); - needsInvalidate = true; - } - } else { - if (mBackground != null) { - mBackground.setBounds(mActionBarView.getLeft(), mActionBarView.getTop(), - mActionBarView.getRight(), mActionBarView.getBottom()); - needsInvalidate = true; - } - if ((mIsStacked = hasTabs && mStackedBackground != null)) { - mStackedBackground.setBounds(mTabContainer.getLeft(), mTabContainer.getTop(), - mTabContainer.getRight(), mTabContainer.getBottom()); - needsInvalidate = true; - } - } - - if (needsInvalidate) { - invalidate(); - } - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/ActionBarContextView.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/ActionBarContextView.java deleted file mode 100644 index 9ec250f38..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/ActionBarContextView.java +++ /dev/null @@ -1,518 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.actionbarsherlock.internal.widget; - -import android.content.Context; -import android.content.res.TypedArray; -import android.graphics.drawable.Drawable; -import android.text.TextUtils; -import android.util.AttributeSet; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.view.accessibility.AccessibilityEvent; -import android.view.animation.DecelerateInterpolator; -import android.widget.LinearLayout; -import android.widget.TextView; - -import com.actionbarsherlock.R; -import com.actionbarsherlock.internal.nineoldandroids.animation.Animator; -import com.actionbarsherlock.internal.nineoldandroids.animation.Animator.AnimatorListener; -import com.actionbarsherlock.internal.nineoldandroids.animation.AnimatorSet; -import com.actionbarsherlock.internal.nineoldandroids.animation.ObjectAnimator; -import com.actionbarsherlock.internal.nineoldandroids.view.animation.AnimatorProxy; -import com.actionbarsherlock.internal.nineoldandroids.widget.NineLinearLayout; -import com.actionbarsherlock.internal.view.menu.ActionMenuPresenter; -import com.actionbarsherlock.internal.view.menu.ActionMenuView; -import com.actionbarsherlock.internal.view.menu.MenuBuilder; -import com.actionbarsherlock.view.ActionMode; - -/** - * @hide - */ -public class ActionBarContextView extends AbsActionBarView implements AnimatorListener { - //UNUSED private static final String TAG = "ActionBarContextView"; - - private CharSequence mTitle; - private CharSequence mSubtitle; - - private NineLinearLayout mClose; - private View mCustomView; - private LinearLayout mTitleLayout; - private TextView mTitleView; - private TextView mSubtitleView; - private int mTitleStyleRes; - private int mSubtitleStyleRes; - private Drawable mSplitBackground; - - private Animator mCurrentAnimation; - private boolean mAnimateInOnLayout; - private int mAnimationMode; - - private static final int ANIMATE_IDLE = 0; - private static final int ANIMATE_IN = 1; - private static final int ANIMATE_OUT = 2; - - public ActionBarContextView(Context context) { - this(context, null); - } - - public ActionBarContextView(Context context, AttributeSet attrs) { - this(context, attrs, R.attr.actionModeStyle); - } - - public ActionBarContextView(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - - TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SherlockActionMode, defStyle, 0); - setBackgroundDrawable(a.getDrawable( - R.styleable.SherlockActionMode_background)); - mTitleStyleRes = a.getResourceId( - R.styleable.SherlockActionMode_titleTextStyle, 0); - mSubtitleStyleRes = a.getResourceId( - R.styleable.SherlockActionMode_subtitleTextStyle, 0); - - mContentHeight = a.getLayoutDimension( - R.styleable.SherlockActionMode_height, 0); - - mSplitBackground = a.getDrawable( - R.styleable.SherlockActionMode_backgroundSplit); - - a.recycle(); - } - - @Override - public void onDetachedFromWindow() { - super.onDetachedFromWindow(); - if (mActionMenuPresenter != null) { - mActionMenuPresenter.hideOverflowMenu(); - mActionMenuPresenter.hideSubMenus(); - } - } - - @Override - public void setSplitActionBar(boolean split) { - if (mSplitActionBar != split) { - if (mActionMenuPresenter != null) { - // Mode is already active; move everything over and adjust the menu itself. - final LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, - LayoutParams.MATCH_PARENT); - if (!split) { - mMenuView = (ActionMenuView) mActionMenuPresenter.getMenuView(this); - mMenuView.setBackgroundDrawable(null); - final ViewGroup oldParent = (ViewGroup) mMenuView.getParent(); - if (oldParent != null) oldParent.removeView(mMenuView); - addView(mMenuView, layoutParams); - } else { - // Allow full screen width in split mode. - mActionMenuPresenter.setWidthLimit( - getContext().getResources().getDisplayMetrics().widthPixels, true); - // No limit to the item count; use whatever will fit. - mActionMenuPresenter.setItemLimit(Integer.MAX_VALUE); - // Span the whole width - layoutParams.width = LayoutParams.MATCH_PARENT; - layoutParams.height = mContentHeight; - mMenuView = (ActionMenuView) mActionMenuPresenter.getMenuView(this); - mMenuView.setBackgroundDrawable(mSplitBackground); - final ViewGroup oldParent = (ViewGroup) mMenuView.getParent(); - if (oldParent != null) oldParent.removeView(mMenuView); - mSplitView.addView(mMenuView, layoutParams); - } - } - super.setSplitActionBar(split); - } - } - - public void setContentHeight(int height) { - mContentHeight = height; - } - - public void setCustomView(View view) { - if (mCustomView != null) { - removeView(mCustomView); - } - mCustomView = view; - if (mTitleLayout != null) { - removeView(mTitleLayout); - mTitleLayout = null; - } - if (view != null) { - addView(view); - } - requestLayout(); - } - - public void setTitle(CharSequence title) { - mTitle = title; - initTitle(); - } - - public void setSubtitle(CharSequence subtitle) { - mSubtitle = subtitle; - initTitle(); - } - - public CharSequence getTitle() { - return mTitle; - } - - public CharSequence getSubtitle() { - return mSubtitle; - } - - private void initTitle() { - if (mTitleLayout == null) { - LayoutInflater inflater = LayoutInflater.from(getContext()); - inflater.inflate(R.layout.abs__action_bar_title_item, this); - mTitleLayout = (LinearLayout) getChildAt(getChildCount() - 1); - mTitleView = (TextView) mTitleLayout.findViewById(R.id.abs__action_bar_title); - mSubtitleView = (TextView) mTitleLayout.findViewById(R.id.abs__action_bar_subtitle); - if (mTitleStyleRes != 0) { - mTitleView.setTextAppearance(mContext, mTitleStyleRes); - } - if (mSubtitleStyleRes != 0) { - mSubtitleView.setTextAppearance(mContext, mSubtitleStyleRes); - } - } - - mTitleView.setText(mTitle); - mSubtitleView.setText(mSubtitle); - - final boolean hasTitle = !TextUtils.isEmpty(mTitle); - final boolean hasSubtitle = !TextUtils.isEmpty(mSubtitle); - mSubtitleView.setVisibility(hasSubtitle ? VISIBLE : GONE); - mTitleLayout.setVisibility(hasTitle || hasSubtitle ? VISIBLE : GONE); - if (mTitleLayout.getParent() == null) { - addView(mTitleLayout); - } - } - - public void initForMode(final ActionMode mode) { - if (mClose == null) { - LayoutInflater inflater = LayoutInflater.from(mContext); - mClose = (NineLinearLayout)inflater.inflate(R.layout.abs__action_mode_close_item, this, false); - addView(mClose); - } else if (mClose.getParent() == null) { - addView(mClose); - } - - View closeButton = mClose.findViewById(R.id.abs__action_mode_close_button); - closeButton.setOnClickListener(new OnClickListener() { - public void onClick(View v) { - mode.finish(); - } - }); - - final MenuBuilder menu = (MenuBuilder) mode.getMenu(); - if (mActionMenuPresenter != null) { - mActionMenuPresenter.dismissPopupMenus(); - } - mActionMenuPresenter = new ActionMenuPresenter(mContext); - mActionMenuPresenter.setReserveOverflow(true); - - final LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, - LayoutParams.MATCH_PARENT); - if (!mSplitActionBar) { - menu.addMenuPresenter(mActionMenuPresenter); - mMenuView = (ActionMenuView) mActionMenuPresenter.getMenuView(this); - mMenuView.setBackgroundDrawable(null); - addView(mMenuView, layoutParams); - } else { - // Allow full screen width in split mode. - mActionMenuPresenter.setWidthLimit( - getContext().getResources().getDisplayMetrics().widthPixels, true); - // No limit to the item count; use whatever will fit. - mActionMenuPresenter.setItemLimit(Integer.MAX_VALUE); - // Span the whole width - layoutParams.width = LayoutParams.MATCH_PARENT; - layoutParams.height = mContentHeight; - menu.addMenuPresenter(mActionMenuPresenter); - mMenuView = (ActionMenuView) mActionMenuPresenter.getMenuView(this); - mMenuView.setBackgroundDrawable(mSplitBackground); - mSplitView.addView(mMenuView, layoutParams); - } - - mAnimateInOnLayout = true; - } - - public void closeMode() { - if (mAnimationMode == ANIMATE_OUT) { - // Called again during close; just finish what we were doing. - return; - } - if (mClose == null) { - killMode(); - return; - } - - finishAnimation(); - mAnimationMode = ANIMATE_OUT; - mCurrentAnimation = makeOutAnimation(); - mCurrentAnimation.start(); - } - - private void finishAnimation() { - final Animator a = mCurrentAnimation; - if (a != null) { - mCurrentAnimation = null; - a.end(); - } - } - - public void killMode() { - finishAnimation(); - removeAllViews(); - if (mSplitView != null) { - mSplitView.removeView(mMenuView); - } - mCustomView = null; - mMenuView = null; - mAnimateInOnLayout = false; - } - - @Override - public boolean showOverflowMenu() { - if (mActionMenuPresenter != null) { - return mActionMenuPresenter.showOverflowMenu(); - } - return false; - } - - @Override - public boolean hideOverflowMenu() { - if (mActionMenuPresenter != null) { - return mActionMenuPresenter.hideOverflowMenu(); - } - return false; - } - - @Override - public boolean isOverflowMenuShowing() { - if (mActionMenuPresenter != null) { - return mActionMenuPresenter.isOverflowMenuShowing(); - } - return false; - } - - @Override - protected ViewGroup.LayoutParams generateDefaultLayoutParams() { - // Used by custom views if they don't supply layout params. Everything else - // added to an ActionBarContextView should have them already. - return new MarginLayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); - } - - @Override - public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) { - return new MarginLayoutParams(getContext(), attrs); - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - final int widthMode = MeasureSpec.getMode(widthMeasureSpec); - if (widthMode != MeasureSpec.EXACTLY) { - throw new IllegalStateException(getClass().getSimpleName() + " can only be used " + - "with android:layout_width=\"match_parent\" (or fill_parent)"); - } - - final int heightMode = MeasureSpec.getMode(heightMeasureSpec); - if (heightMode == MeasureSpec.UNSPECIFIED) { - throw new IllegalStateException(getClass().getSimpleName() + " can only be used " + - "with android:layout_height=\"wrap_content\""); - } - - final int contentWidth = MeasureSpec.getSize(widthMeasureSpec); - - int maxHeight = mContentHeight > 0 ? - mContentHeight : MeasureSpec.getSize(heightMeasureSpec); - - final int verticalPadding = getPaddingTop() + getPaddingBottom(); - int availableWidth = contentWidth - getPaddingLeft() - getPaddingRight(); - final int height = maxHeight - verticalPadding; - final int childSpecHeight = MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST); - - if (mClose != null) { - availableWidth = measureChildView(mClose, availableWidth, childSpecHeight, 0); - MarginLayoutParams lp = (MarginLayoutParams) mClose.getLayoutParams(); - availableWidth -= lp.leftMargin + lp.rightMargin; - } - - if (mMenuView != null && mMenuView.getParent() == this) { - availableWidth = measureChildView(mMenuView, availableWidth, - childSpecHeight, 0); - } - - if (mTitleLayout != null && mCustomView == null) { - availableWidth = measureChildView(mTitleLayout, availableWidth, childSpecHeight, 0); - } - - if (mCustomView != null) { - ViewGroup.LayoutParams lp = mCustomView.getLayoutParams(); - final int customWidthMode = lp.width != LayoutParams.WRAP_CONTENT ? - MeasureSpec.EXACTLY : MeasureSpec.AT_MOST; - final int customWidth = lp.width >= 0 ? - Math.min(lp.width, availableWidth) : availableWidth; - final int customHeightMode = lp.height != LayoutParams.WRAP_CONTENT ? - MeasureSpec.EXACTLY : MeasureSpec.AT_MOST; - final int customHeight = lp.height >= 0 ? - Math.min(lp.height, height) : height; - mCustomView.measure(MeasureSpec.makeMeasureSpec(customWidth, customWidthMode), - MeasureSpec.makeMeasureSpec(customHeight, customHeightMode)); - } - - if (mContentHeight <= 0) { - int measuredHeight = 0; - final int count = getChildCount(); - for (int i = 0; i < count; i++) { - View v = getChildAt(i); - int paddedViewHeight = v.getMeasuredHeight() + verticalPadding; - if (paddedViewHeight > measuredHeight) { - measuredHeight = paddedViewHeight; - } - } - setMeasuredDimension(contentWidth, measuredHeight); - } else { - setMeasuredDimension(contentWidth, maxHeight); - } - } - - private Animator makeInAnimation() { - mClose.setTranslationX(-mClose.getWidth() - - ((MarginLayoutParams) mClose.getLayoutParams()).leftMargin); - ObjectAnimator buttonAnimator = ObjectAnimator.ofFloat(mClose, "translationX", 0); - buttonAnimator.setDuration(200); - buttonAnimator.addListener(this); - buttonAnimator.setInterpolator(new DecelerateInterpolator()); - - AnimatorSet set = new AnimatorSet(); - AnimatorSet.Builder b = set.play(buttonAnimator); - - if (mMenuView != null) { - final int count = mMenuView.getChildCount(); - if (count > 0) { - for (int i = count - 1, j = 0; i >= 0; i--, j++) { - AnimatorProxy child = AnimatorProxy.wrap(mMenuView.getChildAt(i)); - child.setScaleY(0); - ObjectAnimator a = ObjectAnimator.ofFloat(child, "scaleY", 0, 1); - a.setDuration(100); - a.setStartDelay(j * 70); - b.with(a); - } - } - } - - return set; - } - - private Animator makeOutAnimation() { - ObjectAnimator buttonAnimator = ObjectAnimator.ofFloat(mClose, "translationX", - -mClose.getWidth() - ((MarginLayoutParams) mClose.getLayoutParams()).leftMargin); - buttonAnimator.setDuration(200); - buttonAnimator.addListener(this); - buttonAnimator.setInterpolator(new DecelerateInterpolator()); - - AnimatorSet set = new AnimatorSet(); - AnimatorSet.Builder b = set.play(buttonAnimator); - - if (mMenuView != null) { - final int count = mMenuView.getChildCount(); - if (count > 0) { - for (int i = 0; i < 0; i++) { - AnimatorProxy child = AnimatorProxy.wrap(mMenuView.getChildAt(i)); - child.setScaleY(0); - ObjectAnimator a = ObjectAnimator.ofFloat(child, "scaleY", 0); - a.setDuration(100); - a.setStartDelay(i * 70); - b.with(a); - } - } - } - - return set; - } - - @Override - protected void onLayout(boolean changed, int l, int t, int r, int b) { - int x = getPaddingLeft(); - final int y = getPaddingTop(); - final int contentHeight = b - t - getPaddingTop() - getPaddingBottom(); - - if (mClose != null && mClose.getVisibility() != GONE) { - MarginLayoutParams lp = (MarginLayoutParams) mClose.getLayoutParams(); - x += lp.leftMargin; - x += positionChild(mClose, x, y, contentHeight); - x += lp.rightMargin; - - if (mAnimateInOnLayout) { - mAnimationMode = ANIMATE_IN; - mCurrentAnimation = makeInAnimation(); - mCurrentAnimation.start(); - mAnimateInOnLayout = false; - } - } - - if (mTitleLayout != null && mCustomView == null) { - x += positionChild(mTitleLayout, x, y, contentHeight); - } - - if (mCustomView != null) { - x += positionChild(mCustomView, x, y, contentHeight); - } - - x = r - l - getPaddingRight(); - - if (mMenuView != null) { - x -= positionChildInverse(mMenuView, x, y, contentHeight); - } - } - - @Override - public void onAnimationStart(Animator animation) { - } - - @Override - public void onAnimationEnd(Animator animation) { - if (mAnimationMode == ANIMATE_OUT) { - killMode(); - } - mAnimationMode = ANIMATE_IDLE; - } - - @Override - public void onAnimationCancel(Animator animation) { - } - - @Override - public void onAnimationRepeat(Animator animation) { - } - - @Override - public boolean shouldDelayChildPressedState() { - return false; - } - - @Override - public void onInitializeAccessibilityEvent(AccessibilityEvent event) { - if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) { - // Action mode started - //TODO event.setSource(this); - event.setClassName(getClass().getName()); - event.setPackageName(getContext().getPackageName()); - event.setContentDescription(mTitle); - } else { - //TODO super.onInitializeAccessibilityEvent(event); - } - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/ActionBarView.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/ActionBarView.java deleted file mode 100644 index 4636de17f..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/ActionBarView.java +++ /dev/null @@ -1,1548 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.widget; - -import org.xmlpull.v1.XmlPullParser; -import android.app.Activity; -import android.content.Context; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.content.pm.PackageManager.NameNotFoundException; -import android.content.res.AssetManager; -import android.content.res.Configuration; -import android.content.res.TypedArray; -import android.content.res.XmlResourceParser; -import android.graphics.drawable.Drawable; -import android.os.Build; -import android.os.Parcel; -import android.os.Parcelable; -import android.text.TextUtils; -import android.util.AttributeSet; -import android.util.Log; -import android.view.Gravity; -import android.view.LayoutInflater; -import android.view.MotionEvent; -import android.view.View; -import android.view.ViewGroup; -import android.view.ViewParent; -import android.view.accessibility.AccessibilityEvent; -import android.widget.FrameLayout; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.SpinnerAdapter; -import android.widget.TextView; - -import com.actionbarsherlock.R; -import com.actionbarsherlock.app.ActionBar; -import com.actionbarsherlock.app.ActionBar.OnNavigationListener; -import com.actionbarsherlock.internal.ActionBarSherlockCompat; -import com.actionbarsherlock.internal.view.menu.ActionMenuItem; -import com.actionbarsherlock.internal.view.menu.ActionMenuPresenter; -import com.actionbarsherlock.internal.view.menu.ActionMenuView; -import com.actionbarsherlock.internal.view.menu.MenuBuilder; -import com.actionbarsherlock.internal.view.menu.MenuItemImpl; -import com.actionbarsherlock.internal.view.menu.MenuPresenter; -import com.actionbarsherlock.internal.view.menu.MenuView; -import com.actionbarsherlock.internal.view.menu.SubMenuBuilder; -import com.actionbarsherlock.view.CollapsibleActionView; -import com.actionbarsherlock.view.Menu; -import com.actionbarsherlock.view.MenuItem; -import com.actionbarsherlock.view.Window; - -import static com.actionbarsherlock.internal.ResourcesCompat.getResources_getBoolean; - -/** - * @hide - */ -public class ActionBarView extends AbsActionBarView { - private static final String TAG = "ActionBarView"; - private static final boolean DEBUG = false; - - /** - * Display options applied by default - */ - public static final int DISPLAY_DEFAULT = 0; - - /** - * Display options that require re-layout as opposed to a simple invalidate - */ - private static final int DISPLAY_RELAYOUT_MASK = - ActionBar.DISPLAY_SHOW_HOME | - ActionBar.DISPLAY_USE_LOGO | - ActionBar.DISPLAY_HOME_AS_UP | - ActionBar.DISPLAY_SHOW_CUSTOM | - ActionBar.DISPLAY_SHOW_TITLE; - - private static final int DEFAULT_CUSTOM_GRAVITY = Gravity.LEFT | Gravity.CENTER_VERTICAL; - - private int mNavigationMode; - private int mDisplayOptions = -1; - private CharSequence mTitle; - private CharSequence mSubtitle; - private Drawable mIcon; - private Drawable mLogo; - - private HomeView mHomeLayout; - private HomeView mExpandedHomeLayout; - private LinearLayout mTitleLayout; - private TextView mTitleView; - private TextView mSubtitleView; - private View mTitleUpView; - - private IcsSpinner mSpinner; - private IcsLinearLayout mListNavLayout; - private ScrollingTabContainerView mTabScrollView; - private View mCustomNavView; - private IcsProgressBar mProgressView; - private IcsProgressBar mIndeterminateProgressView; - - private int mProgressBarPadding; - private int mItemPadding; - - private int mTitleStyleRes; - private int mSubtitleStyleRes; - private int mProgressStyle; - private int mIndeterminateProgressStyle; - - private boolean mUserTitle; - private boolean mIncludeTabs; - private boolean mIsCollapsable; - private boolean mIsCollapsed; - - private MenuBuilder mOptionsMenu; - - private ActionBarContextView mContextView; - - private ActionMenuItem mLogoNavItem; - - private SpinnerAdapter mSpinnerAdapter; - private OnNavigationListener mCallback; - - //UNUSED private Runnable mTabSelector; - - private ExpandedActionViewMenuPresenter mExpandedMenuPresenter; - View mExpandedActionView; - - Window.Callback mWindowCallback; - - @SuppressWarnings("rawtypes") - private final IcsAdapterView.OnItemSelectedListener mNavItemSelectedListener = - new IcsAdapterView.OnItemSelectedListener() { - public void onItemSelected(IcsAdapterView parent, View view, int position, long id) { - if (mCallback != null) { - mCallback.onNavigationItemSelected(position, id); - } - } - public void onNothingSelected(IcsAdapterView parent) { - // Do nothing - } - }; - - private final OnClickListener mExpandedActionViewUpListener = new OnClickListener() { - @Override - public void onClick(View v) { - final MenuItemImpl item = mExpandedMenuPresenter.mCurrentExpandedItem; - if (item != null) { - item.collapseActionView(); - } - } - }; - - private final OnClickListener mUpClickListener = new OnClickListener() { - public void onClick(View v) { - mWindowCallback.onMenuItemSelected(Window.FEATURE_OPTIONS_PANEL, mLogoNavItem); - } - }; - - public ActionBarView(Context context, AttributeSet attrs) { - super(context, attrs); - - // Background is always provided by the container. - setBackgroundResource(0); - - TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SherlockActionBar, - R.attr.actionBarStyle, 0); - - ApplicationInfo appInfo = context.getApplicationInfo(); - PackageManager pm = context.getPackageManager(); - mNavigationMode = a.getInt(R.styleable.SherlockActionBar_navigationMode, - ActionBar.NAVIGATION_MODE_STANDARD); - mTitle = a.getText(R.styleable.SherlockActionBar_title); - mSubtitle = a.getText(R.styleable.SherlockActionBar_subtitle); - - mLogo = a.getDrawable(R.styleable.SherlockActionBar_logo); - if (mLogo == null) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { - if (context instanceof Activity) { - //Even though native methods existed in API 9 and 10 they don't work - //so just parse the manifest to look for the logo pre-Honeycomb - final int resId = loadLogoFromManifest((Activity) context); - if (resId != 0) { - mLogo = context.getResources().getDrawable(resId); - } - } - } else { - if (context instanceof Activity) { - try { - mLogo = pm.getActivityLogo(((Activity) context).getComponentName()); - } catch (NameNotFoundException e) { - Log.e(TAG, "Activity component name not found!", e); - } - } - if (mLogo == null) { - mLogo = appInfo.loadLogo(pm); - } - } - } - - mIcon = a.getDrawable(R.styleable.SherlockActionBar_icon); - if (mIcon == null) { - if (context instanceof Activity) { - try { - mIcon = pm.getActivityIcon(((Activity) context).getComponentName()); - } catch (NameNotFoundException e) { - Log.e(TAG, "Activity component name not found!", e); - } - } - if (mIcon == null) { - mIcon = appInfo.loadIcon(pm); - } - } - - final LayoutInflater inflater = LayoutInflater.from(context); - - final int homeResId = a.getResourceId( - R.styleable.SherlockActionBar_homeLayout, - R.layout.abs__action_bar_home); - - mHomeLayout = (HomeView) inflater.inflate(homeResId, this, false); - - mExpandedHomeLayout = (HomeView) inflater.inflate(homeResId, this, false); - mExpandedHomeLayout.setUp(true); - mExpandedHomeLayout.setOnClickListener(mExpandedActionViewUpListener); - mExpandedHomeLayout.setContentDescription(getResources().getText( - R.string.abs__action_bar_up_description)); - - mTitleStyleRes = a.getResourceId(R.styleable.SherlockActionBar_titleTextStyle, 0); - mSubtitleStyleRes = a.getResourceId(R.styleable.SherlockActionBar_subtitleTextStyle, 0); - mProgressStyle = a.getResourceId(R.styleable.SherlockActionBar_progressBarStyle, 0); - mIndeterminateProgressStyle = a.getResourceId( - R.styleable.SherlockActionBar_indeterminateProgressStyle, 0); - - mProgressBarPadding = a.getDimensionPixelOffset(R.styleable.SherlockActionBar_progressBarPadding, 0); - mItemPadding = a.getDimensionPixelOffset(R.styleable.SherlockActionBar_itemPadding, 0); - - setDisplayOptions(a.getInt(R.styleable.SherlockActionBar_displayOptions, DISPLAY_DEFAULT)); - - final int customNavId = a.getResourceId(R.styleable.SherlockActionBar_customNavigationLayout, 0); - if (customNavId != 0) { - mCustomNavView = inflater.inflate(customNavId, this, false); - mNavigationMode = ActionBar.NAVIGATION_MODE_STANDARD; - setDisplayOptions(mDisplayOptions | ActionBar.DISPLAY_SHOW_CUSTOM); - } - - mContentHeight = a.getLayoutDimension(R.styleable.SherlockActionBar_height, 0); - - a.recycle(); - - mLogoNavItem = new ActionMenuItem(context, 0, android.R.id.home, 0, 0, mTitle); - mHomeLayout.setOnClickListener(mUpClickListener); - mHomeLayout.setClickable(true); - mHomeLayout.setFocusable(true); - } - - /** - * Attempt to programmatically load the logo from the manifest file of an - * activity by using an XML pull parser. This should allow us to read the - * logo attribute regardless of the platform it is being run on. - * - * @param activity Activity instance. - * @return Logo resource ID. - */ - private static int loadLogoFromManifest(Activity activity) { - int logo = 0; - try { - final String thisPackage = activity.getClass().getName(); - if (DEBUG) Log.i(TAG, "Parsing AndroidManifest.xml for " + thisPackage); - - final String packageName = activity.getApplicationInfo().packageName; - final AssetManager am = activity.createPackageContext(packageName, 0).getAssets(); - final XmlResourceParser xml = am.openXmlResourceParser("AndroidManifest.xml"); - - int eventType = xml.getEventType(); - while (eventType != XmlPullParser.END_DOCUMENT) { - if (eventType == XmlPullParser.START_TAG) { - String name = xml.getName(); - - if ("application".equals(name)) { - //Check if the has the attribute - if (DEBUG) Log.d(TAG, "Got "); - - for (int i = xml.getAttributeCount() - 1; i >= 0; i--) { - if (DEBUG) Log.d(TAG, xml.getAttributeName(i) + ": " + xml.getAttributeValue(i)); - - if ("logo".equals(xml.getAttributeName(i))) { - logo = xml.getAttributeResourceValue(i, 0); - break; //out of for loop - } - } - } else if ("activity".equals(name)) { - //Check if the is us and has the attribute - if (DEBUG) Log.d(TAG, "Got "); - Integer activityLogo = null; - String activityPackage = null; - boolean isOurActivity = false; - - for (int i = xml.getAttributeCount() - 1; i >= 0; i--) { - if (DEBUG) Log.d(TAG, xml.getAttributeName(i) + ": " + xml.getAttributeValue(i)); - - //We need both uiOptions and name attributes - String attrName = xml.getAttributeName(i); - if ("logo".equals(attrName)) { - activityLogo = xml.getAttributeResourceValue(i, 0); - } else if ("name".equals(attrName)) { - activityPackage = ActionBarSherlockCompat.cleanActivityName(packageName, xml.getAttributeValue(i)); - if (!thisPackage.equals(activityPackage)) { - break; //on to the next - } - isOurActivity = true; - } - - //Make sure we have both attributes before processing - if ((activityLogo != null) && (activityPackage != null)) { - //Our activity, logo specified, override with our value - logo = activityLogo.intValue(); - } - } - if (isOurActivity) { - //If we matched our activity but it had no logo don't - //do any more processing of the manifest - break; - } - } - } - eventType = xml.nextToken(); - } - } catch (Exception e) { - e.printStackTrace(); - } - if (DEBUG) Log.i(TAG, "Returning " + Integer.toHexString(logo)); - return logo; - } - - /* - * Must be public so we can dispatch pre-2.2 via ActionBarImpl. - */ - @Override - public void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - - mTitleView = null; - mSubtitleView = null; - mTitleUpView = null; - if (mTitleLayout != null && mTitleLayout.getParent() == this) { - removeView(mTitleLayout); - } - mTitleLayout = null; - if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0) { - initTitle(); - } - - if (mTabScrollView != null && mIncludeTabs) { - ViewGroup.LayoutParams lp = mTabScrollView.getLayoutParams(); - if (lp != null) { - lp.width = LayoutParams.WRAP_CONTENT; - lp.height = LayoutParams.MATCH_PARENT; - } - mTabScrollView.setAllowCollapse(true); - } - } - - /** - * Set the window callback used to invoke menu items; used for dispatching home button presses. - * @param cb Window callback to dispatch to - */ - public void setWindowCallback(Window.Callback cb) { - mWindowCallback = cb; - } - - @Override - public void onDetachedFromWindow() { - super.onDetachedFromWindow(); - //UNUSED removeCallbacks(mTabSelector); - if (mActionMenuPresenter != null) { - mActionMenuPresenter.hideOverflowMenu(); - mActionMenuPresenter.hideSubMenus(); - } - } - - @Override - public boolean shouldDelayChildPressedState() { - return false; - } - - public void initProgress() { - mProgressView = new IcsProgressBar(mContext, null, 0, mProgressStyle); - mProgressView.setId(R.id.abs__progress_horizontal); - mProgressView.setMax(10000); - addView(mProgressView); - } - - public void initIndeterminateProgress() { - mIndeterminateProgressView = new IcsProgressBar(mContext, null, 0, mIndeterminateProgressStyle); - mIndeterminateProgressView.setId(R.id.abs__progress_circular); - addView(mIndeterminateProgressView); - } - - @Override - public void setSplitActionBar(boolean splitActionBar) { - if (mSplitActionBar != splitActionBar) { - if (mMenuView != null) { - final ViewGroup oldParent = (ViewGroup) mMenuView.getParent(); - if (oldParent != null) { - oldParent.removeView(mMenuView); - } - if (splitActionBar) { - if (mSplitView != null) { - mSplitView.addView(mMenuView); - } - } else { - addView(mMenuView); - } - } - if (mSplitView != null) { - mSplitView.setVisibility(splitActionBar ? VISIBLE : GONE); - } - super.setSplitActionBar(splitActionBar); - } - } - - public boolean isSplitActionBar() { - return mSplitActionBar; - } - - public boolean hasEmbeddedTabs() { - return mIncludeTabs; - } - - public void setEmbeddedTabView(ScrollingTabContainerView tabs) { - if (mTabScrollView != null) { - removeView(mTabScrollView); - } - mTabScrollView = tabs; - mIncludeTabs = tabs != null; - if (mIncludeTabs && mNavigationMode == ActionBar.NAVIGATION_MODE_TABS) { - addView(mTabScrollView); - ViewGroup.LayoutParams lp = mTabScrollView.getLayoutParams(); - lp.width = LayoutParams.WRAP_CONTENT; - lp.height = LayoutParams.MATCH_PARENT; - tabs.setAllowCollapse(true); - } - } - - public void setCallback(OnNavigationListener callback) { - mCallback = callback; - } - - public void setMenu(Menu menu, MenuPresenter.Callback cb) { - if (menu == mOptionsMenu) return; - - if (mOptionsMenu != null) { - mOptionsMenu.removeMenuPresenter(mActionMenuPresenter); - mOptionsMenu.removeMenuPresenter(mExpandedMenuPresenter); - } - - MenuBuilder builder = (MenuBuilder) menu; - mOptionsMenu = builder; - if (mMenuView != null) { - final ViewGroup oldParent = (ViewGroup) mMenuView.getParent(); - if (oldParent != null) { - oldParent.removeView(mMenuView); - } - } - if (mActionMenuPresenter == null) { - mActionMenuPresenter = new ActionMenuPresenter(mContext); - mActionMenuPresenter.setCallback(cb); - mActionMenuPresenter.setId(R.id.abs__action_menu_presenter); - mExpandedMenuPresenter = new ExpandedActionViewMenuPresenter(); - } - - ActionMenuView menuView; - final LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, - LayoutParams.MATCH_PARENT); - if (!mSplitActionBar) { - mActionMenuPresenter.setExpandedActionViewsExclusive( - getResources_getBoolean(getContext(), - R.bool.abs__action_bar_expanded_action_views_exclusive)); - configPresenters(builder); - menuView = (ActionMenuView) mActionMenuPresenter.getMenuView(this); - final ViewGroup oldParent = (ViewGroup) menuView.getParent(); - if (oldParent != null && oldParent != this) { - oldParent.removeView(menuView); - } - addView(menuView, layoutParams); - } else { - mActionMenuPresenter.setExpandedActionViewsExclusive(false); - // Allow full screen width in split mode. - mActionMenuPresenter.setWidthLimit( - getContext().getResources().getDisplayMetrics().widthPixels, true); - // No limit to the item count; use whatever will fit. - mActionMenuPresenter.setItemLimit(Integer.MAX_VALUE); - // Span the whole width - layoutParams.width = LayoutParams.MATCH_PARENT; - configPresenters(builder); - menuView = (ActionMenuView) mActionMenuPresenter.getMenuView(this); - if (mSplitView != null) { - final ViewGroup oldParent = (ViewGroup) menuView.getParent(); - if (oldParent != null && oldParent != mSplitView) { - oldParent.removeView(menuView); - } - menuView.setVisibility(getAnimatedVisibility()); - mSplitView.addView(menuView, layoutParams); - } else { - // We'll add this later if we missed it this time. - menuView.setLayoutParams(layoutParams); - } - } - mMenuView = menuView; - } - - private void configPresenters(MenuBuilder builder) { - if (builder != null) { - builder.addMenuPresenter(mActionMenuPresenter); - builder.addMenuPresenter(mExpandedMenuPresenter); - } else { - mActionMenuPresenter.initForMenu(mContext, null); - mExpandedMenuPresenter.initForMenu(mContext, null); - mActionMenuPresenter.updateMenuView(true); - mExpandedMenuPresenter.updateMenuView(true); - } - } - - public boolean hasExpandedActionView() { - return mExpandedMenuPresenter != null && - mExpandedMenuPresenter.mCurrentExpandedItem != null; - } - - public void collapseActionView() { - final MenuItemImpl item = mExpandedMenuPresenter == null ? null : - mExpandedMenuPresenter.mCurrentExpandedItem; - if (item != null) { - item.collapseActionView(); - } - } - - public void setCustomNavigationView(View view) { - final boolean showCustom = (mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0; - if (mCustomNavView != null && showCustom) { - removeView(mCustomNavView); - } - mCustomNavView = view; - if (mCustomNavView != null && showCustom) { - addView(mCustomNavView); - } - } - - public CharSequence getTitle() { - return mTitle; - } - - /** - * Set the action bar title. This will always replace or override window titles. - * @param title Title to set - * - * @see #setWindowTitle(CharSequence) - */ - public void setTitle(CharSequence title) { - mUserTitle = true; - setTitleImpl(title); - } - - /** - * Set the window title. A window title will always be replaced or overridden by a user title. - * @param title Title to set - * - * @see #setTitle(CharSequence) - */ - public void setWindowTitle(CharSequence title) { - if (!mUserTitle) { - setTitleImpl(title); - } - } - - private void setTitleImpl(CharSequence title) { - mTitle = title; - if (mTitleView != null) { - mTitleView.setText(title); - final boolean visible = mExpandedActionView == null && - (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0 && - (!TextUtils.isEmpty(mTitle) || !TextUtils.isEmpty(mSubtitle)); - mTitleLayout.setVisibility(visible ? VISIBLE : GONE); - } - if (mLogoNavItem != null) { - mLogoNavItem.setTitle(title); - } - } - - public CharSequence getSubtitle() { - return mSubtitle; - } - - public void setSubtitle(CharSequence subtitle) { - mSubtitle = subtitle; - if (mSubtitleView != null) { - mSubtitleView.setText(subtitle); - mSubtitleView.setVisibility(subtitle != null ? VISIBLE : GONE); - final boolean visible = mExpandedActionView == null && - (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0 && - (!TextUtils.isEmpty(mTitle) || !TextUtils.isEmpty(mSubtitle)); - mTitleLayout.setVisibility(visible ? VISIBLE : GONE); - } - } - - public void setHomeButtonEnabled(boolean enable) { - mHomeLayout.setEnabled(enable); - mHomeLayout.setFocusable(enable); - // Make sure the home button has an accurate content description for accessibility. - if (!enable) { - mHomeLayout.setContentDescription(null); - } else if ((mDisplayOptions & ActionBar.DISPLAY_HOME_AS_UP) != 0) { - mHomeLayout.setContentDescription(mContext.getResources().getText( - R.string.abs__action_bar_up_description)); - } else { - mHomeLayout.setContentDescription(mContext.getResources().getText( - R.string.abs__action_bar_home_description)); - } - } - - public void setDisplayOptions(int options) { - final int flagsChanged = mDisplayOptions == -1 ? -1 : options ^ mDisplayOptions; - mDisplayOptions = options; - - if ((flagsChanged & DISPLAY_RELAYOUT_MASK) != 0) { - final boolean showHome = (options & ActionBar.DISPLAY_SHOW_HOME) != 0; - final int vis = showHome && mExpandedActionView == null ? VISIBLE : GONE; - mHomeLayout.setVisibility(vis); - - if ((flagsChanged & ActionBar.DISPLAY_HOME_AS_UP) != 0) { - final boolean setUp = (options & ActionBar.DISPLAY_HOME_AS_UP) != 0; - mHomeLayout.setUp(setUp); - - // Showing home as up implicitly enables interaction with it. - // In honeycomb it was always enabled, so make this transition - // a bit easier for developers in the common case. - // (It would be silly to show it as up without responding to it.) - if (setUp) { - setHomeButtonEnabled(true); - } - } - - if ((flagsChanged & ActionBar.DISPLAY_USE_LOGO) != 0) { - final boolean logoVis = mLogo != null && (options & ActionBar.DISPLAY_USE_LOGO) != 0; - mHomeLayout.setIcon(logoVis ? mLogo : mIcon); - } - - if ((flagsChanged & ActionBar.DISPLAY_SHOW_TITLE) != 0) { - if ((options & ActionBar.DISPLAY_SHOW_TITLE) != 0) { - initTitle(); - } else { - removeView(mTitleLayout); - } - } - - if (mTitleLayout != null && (flagsChanged & - (ActionBar.DISPLAY_HOME_AS_UP | ActionBar.DISPLAY_SHOW_HOME)) != 0) { - final boolean homeAsUp = (mDisplayOptions & ActionBar.DISPLAY_HOME_AS_UP) != 0; - mTitleUpView.setVisibility(!showHome ? (homeAsUp ? VISIBLE : INVISIBLE) : GONE); - mTitleLayout.setEnabled(!showHome && homeAsUp); - } - - if ((flagsChanged & ActionBar.DISPLAY_SHOW_CUSTOM) != 0 && mCustomNavView != null) { - if ((options & ActionBar.DISPLAY_SHOW_CUSTOM) != 0) { - addView(mCustomNavView); - } else { - removeView(mCustomNavView); - } - } - - requestLayout(); - } else { - invalidate(); - } - - // Make sure the home button has an accurate content description for accessibility. - if (!mHomeLayout.isEnabled()) { - mHomeLayout.setContentDescription(null); - } else if ((options & ActionBar.DISPLAY_HOME_AS_UP) != 0) { - mHomeLayout.setContentDescription(mContext.getResources().getText( - R.string.abs__action_bar_up_description)); - } else { - mHomeLayout.setContentDescription(mContext.getResources().getText( - R.string.abs__action_bar_home_description)); - } - } - - public void setIcon(Drawable icon) { - mIcon = icon; - if (icon != null && - ((mDisplayOptions & ActionBar.DISPLAY_USE_LOGO) == 0 || mLogo == null)) { - mHomeLayout.setIcon(icon); - } - } - - public void setIcon(int resId) { - setIcon(mContext.getResources().getDrawable(resId)); - } - - public void setLogo(Drawable logo) { - mLogo = logo; - if (logo != null && (mDisplayOptions & ActionBar.DISPLAY_USE_LOGO) != 0) { - mHomeLayout.setIcon(logo); - } - } - - public void setLogo(int resId) { - setLogo(mContext.getResources().getDrawable(resId)); - } - - public void setNavigationMode(int mode) { - final int oldMode = mNavigationMode; - if (mode != oldMode) { - switch (oldMode) { - case ActionBar.NAVIGATION_MODE_LIST: - if (mListNavLayout != null) { - removeView(mListNavLayout); - } - break; - case ActionBar.NAVIGATION_MODE_TABS: - if (mTabScrollView != null && mIncludeTabs) { - removeView(mTabScrollView); - } - } - - switch (mode) { - case ActionBar.NAVIGATION_MODE_LIST: - if (mSpinner == null) { - mSpinner = new IcsSpinner(mContext, null, - R.attr.actionDropDownStyle); - mListNavLayout = (IcsLinearLayout) LayoutInflater.from(mContext) - .inflate(R.layout.abs__action_bar_tab_bar_view, null); - LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( - LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); - params.gravity = Gravity.CENTER; - mListNavLayout.addView(mSpinner, params); - } - if (mSpinner.getAdapter() != mSpinnerAdapter) { - mSpinner.setAdapter(mSpinnerAdapter); - } - mSpinner.setOnItemSelectedListener(mNavItemSelectedListener); - addView(mListNavLayout); - break; - case ActionBar.NAVIGATION_MODE_TABS: - if (mTabScrollView != null && mIncludeTabs) { - addView(mTabScrollView); - } - break; - } - mNavigationMode = mode; - requestLayout(); - } - } - - public void setDropdownAdapter(SpinnerAdapter adapter) { - mSpinnerAdapter = adapter; - if (mSpinner != null) { - mSpinner.setAdapter(adapter); - } - } - - public SpinnerAdapter getDropdownAdapter() { - return mSpinnerAdapter; - } - - public void setDropdownSelectedPosition(int position) { - mSpinner.setSelection(position); - } - - public int getDropdownSelectedPosition() { - return mSpinner.getSelectedItemPosition(); - } - - public View getCustomNavigationView() { - return mCustomNavView; - } - - public int getNavigationMode() { - return mNavigationMode; - } - - public int getDisplayOptions() { - return mDisplayOptions; - } - - @Override - protected ViewGroup.LayoutParams generateDefaultLayoutParams() { - // Used by custom nav views if they don't supply layout params. Everything else - // added to an ActionBarView should have them already. - return new ActionBar.LayoutParams(DEFAULT_CUSTOM_GRAVITY); - } - - @Override - protected void onFinishInflate() { - super.onFinishInflate(); - - addView(mHomeLayout); - - if (mCustomNavView != null && (mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0) { - final ViewParent parent = mCustomNavView.getParent(); - if (parent != this) { - if (parent instanceof ViewGroup) { - ((ViewGroup) parent).removeView(mCustomNavView); - } - addView(mCustomNavView); - } - } - } - - private void initTitle() { - if (mTitleLayout == null) { - LayoutInflater inflater = LayoutInflater.from(getContext()); - mTitleLayout = (LinearLayout) inflater.inflate(R.layout.abs__action_bar_title_item, - this, false); - mTitleView = (TextView) mTitleLayout.findViewById(R.id.abs__action_bar_title); - mSubtitleView = (TextView) mTitleLayout.findViewById(R.id.abs__action_bar_subtitle); - mTitleUpView = mTitleLayout.findViewById(R.id.abs__up); - - mTitleLayout.setOnClickListener(mUpClickListener); - - if (mTitleStyleRes != 0) { - mTitleView.setTextAppearance(mContext, mTitleStyleRes); - } - if (mTitle != null) { - mTitleView.setText(mTitle); - } - - if (mSubtitleStyleRes != 0) { - mSubtitleView.setTextAppearance(mContext, mSubtitleStyleRes); - } - if (mSubtitle != null) { - mSubtitleView.setText(mSubtitle); - mSubtitleView.setVisibility(VISIBLE); - } - - final boolean homeAsUp = (mDisplayOptions & ActionBar.DISPLAY_HOME_AS_UP) != 0; - final boolean showHome = (mDisplayOptions & ActionBar.DISPLAY_SHOW_HOME) != 0; - mTitleUpView.setVisibility(!showHome ? (homeAsUp ? VISIBLE : INVISIBLE) : GONE); - mTitleLayout.setEnabled(homeAsUp && !showHome); - } - - addView(mTitleLayout); - if (mExpandedActionView != null || - (TextUtils.isEmpty(mTitle) && TextUtils.isEmpty(mSubtitle))) { - // Don't show while in expanded mode or with empty text - mTitleLayout.setVisibility(GONE); - } - } - - public void setContextView(ActionBarContextView view) { - mContextView = view; - } - - public void setCollapsable(boolean collapsable) { - mIsCollapsable = collapsable; - } - - public boolean isCollapsed() { - return mIsCollapsed; - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - final int childCount = getChildCount(); - if (mIsCollapsable) { - int visibleChildren = 0; - for (int i = 0; i < childCount; i++) { - final View child = getChildAt(i); - if (child.getVisibility() != GONE && - !(child == mMenuView && mMenuView.getChildCount() == 0)) { - visibleChildren++; - } - } - - if (visibleChildren == 0) { - // No size for an empty action bar when collapsable. - setMeasuredDimension(0, 0); - mIsCollapsed = true; - return; - } - } - mIsCollapsed = false; - - int widthMode = MeasureSpec.getMode(widthMeasureSpec); - if (widthMode != MeasureSpec.EXACTLY) { - throw new IllegalStateException(getClass().getSimpleName() + " can only be used " + - "with android:layout_width=\"match_parent\" (or fill_parent)"); - } - - int heightMode = MeasureSpec.getMode(heightMeasureSpec); - if (heightMode != MeasureSpec.AT_MOST) { - throw new IllegalStateException(getClass().getSimpleName() + " can only be used " + - "with android:layout_height=\"wrap_content\""); - } - - int contentWidth = MeasureSpec.getSize(widthMeasureSpec); - - int maxHeight = mContentHeight > 0 ? - mContentHeight : MeasureSpec.getSize(heightMeasureSpec); - - final int verticalPadding = getPaddingTop() + getPaddingBottom(); - final int paddingLeft = getPaddingLeft(); - final int paddingRight = getPaddingRight(); - final int height = maxHeight - verticalPadding; - final int childSpecHeight = MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST); - - int availableWidth = contentWidth - paddingLeft - paddingRight; - int leftOfCenter = availableWidth / 2; - int rightOfCenter = leftOfCenter; - - HomeView homeLayout = mExpandedActionView != null ? mExpandedHomeLayout : mHomeLayout; - - if (homeLayout.getVisibility() != GONE) { - final ViewGroup.LayoutParams lp = homeLayout.getLayoutParams(); - int homeWidthSpec; - if (lp.width < 0) { - homeWidthSpec = MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST); - } else { - homeWidthSpec = MeasureSpec.makeMeasureSpec(lp.width, MeasureSpec.EXACTLY); - } - homeLayout.measure(homeWidthSpec, - MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)); - final int homeWidth = homeLayout.getMeasuredWidth() + homeLayout.getLeftOffset(); - availableWidth = Math.max(0, availableWidth - homeWidth); - leftOfCenter = Math.max(0, availableWidth - homeWidth); - } - - if (mMenuView != null && mMenuView.getParent() == this) { - availableWidth = measureChildView(mMenuView, availableWidth, - childSpecHeight, 0); - rightOfCenter = Math.max(0, rightOfCenter - mMenuView.getMeasuredWidth()); - } - - if (mIndeterminateProgressView != null && - mIndeterminateProgressView.getVisibility() != GONE) { - availableWidth = measureChildView(mIndeterminateProgressView, availableWidth, - childSpecHeight, 0); - rightOfCenter = Math.max(0, - rightOfCenter - mIndeterminateProgressView.getMeasuredWidth()); - } - - final boolean showTitle = mTitleLayout != null && mTitleLayout.getVisibility() != GONE && - (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0; - - if (mExpandedActionView == null) { - switch (mNavigationMode) { - case ActionBar.NAVIGATION_MODE_LIST: - if (mListNavLayout != null) { - final int itemPaddingSize = showTitle ? mItemPadding * 2 : mItemPadding; - availableWidth = Math.max(0, availableWidth - itemPaddingSize); - leftOfCenter = Math.max(0, leftOfCenter - itemPaddingSize); - mListNavLayout.measure( - MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST), - MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)); - final int listNavWidth = mListNavLayout.getMeasuredWidth(); - availableWidth = Math.max(0, availableWidth - listNavWidth); - leftOfCenter = Math.max(0, leftOfCenter - listNavWidth); - } - break; - case ActionBar.NAVIGATION_MODE_TABS: - if (mTabScrollView != null) { - final int itemPaddingSize = showTitle ? mItemPadding * 2 : mItemPadding; - availableWidth = Math.max(0, availableWidth - itemPaddingSize); - leftOfCenter = Math.max(0, leftOfCenter - itemPaddingSize); - mTabScrollView.measure( - MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST), - MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)); - final int tabWidth = mTabScrollView.getMeasuredWidth(); - availableWidth = Math.max(0, availableWidth - tabWidth); - leftOfCenter = Math.max(0, leftOfCenter - tabWidth); - } - break; - } - } - - View customView = null; - if (mExpandedActionView != null) { - customView = mExpandedActionView; - } else if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0 && - mCustomNavView != null) { - customView = mCustomNavView; - } - - if (customView != null) { - final ViewGroup.LayoutParams lp = generateLayoutParams(customView.getLayoutParams()); - final ActionBar.LayoutParams ablp = lp instanceof ActionBar.LayoutParams ? - (ActionBar.LayoutParams) lp : null; - - int horizontalMargin = 0; - int verticalMargin = 0; - if (ablp != null) { - horizontalMargin = ablp.leftMargin + ablp.rightMargin; - verticalMargin = ablp.topMargin + ablp.bottomMargin; - } - - // If the action bar is wrapping to its content height, don't allow a custom - // view to MATCH_PARENT. - int customNavHeightMode; - if (mContentHeight <= 0) { - customNavHeightMode = MeasureSpec.AT_MOST; - } else { - customNavHeightMode = lp.height != LayoutParams.WRAP_CONTENT ? - MeasureSpec.EXACTLY : MeasureSpec.AT_MOST; - } - final int customNavHeight = Math.max(0, - (lp.height >= 0 ? Math.min(lp.height, height) : height) - verticalMargin); - - final int customNavWidthMode = lp.width != LayoutParams.WRAP_CONTENT ? - MeasureSpec.EXACTLY : MeasureSpec.AT_MOST; - int customNavWidth = Math.max(0, - (lp.width >= 0 ? Math.min(lp.width, availableWidth) : availableWidth) - - horizontalMargin); - final int hgrav = (ablp != null ? ablp.gravity : DEFAULT_CUSTOM_GRAVITY) & - Gravity.HORIZONTAL_GRAVITY_MASK; - - // Centering a custom view is treated specially; we try to center within the whole - // action bar rather than in the available space. - if (hgrav == Gravity.CENTER_HORIZONTAL && lp.width == LayoutParams.MATCH_PARENT) { - customNavWidth = Math.min(leftOfCenter, rightOfCenter) * 2; - } - - customView.measure( - MeasureSpec.makeMeasureSpec(customNavWidth, customNavWidthMode), - MeasureSpec.makeMeasureSpec(customNavHeight, customNavHeightMode)); - availableWidth -= horizontalMargin + customView.getMeasuredWidth(); - } - - if (mExpandedActionView == null && showTitle) { - availableWidth = measureChildView(mTitleLayout, availableWidth, - MeasureSpec.makeMeasureSpec(mContentHeight, MeasureSpec.EXACTLY), 0); - leftOfCenter = Math.max(0, leftOfCenter - mTitleLayout.getMeasuredWidth()); - } - - if (mContentHeight <= 0) { - int measuredHeight = 0; - for (int i = 0; i < childCount; i++) { - View v = getChildAt(i); - int paddedViewHeight = v.getMeasuredHeight() + verticalPadding; - if (paddedViewHeight > measuredHeight) { - measuredHeight = paddedViewHeight; - } - } - setMeasuredDimension(contentWidth, measuredHeight); - } else { - setMeasuredDimension(contentWidth, maxHeight); - } - - if (mContextView != null) { - mContextView.setContentHeight(getMeasuredHeight()); - } - - if (mProgressView != null && mProgressView.getVisibility() != GONE) { - mProgressView.measure(MeasureSpec.makeMeasureSpec( - contentWidth - mProgressBarPadding * 2, MeasureSpec.EXACTLY), - MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.AT_MOST)); - } - } - - @Override - protected void onLayout(boolean changed, int l, int t, int r, int b) { - int x = getPaddingLeft(); - final int y = getPaddingTop(); - final int contentHeight = b - t - getPaddingTop() - getPaddingBottom(); - - if (contentHeight <= 0) { - // Nothing to do if we can't see anything. - return; - } - - HomeView homeLayout = mExpandedActionView != null ? mExpandedHomeLayout : mHomeLayout; - if (homeLayout.getVisibility() != GONE) { - final int leftOffset = homeLayout.getLeftOffset(); - x += positionChild(homeLayout, x + leftOffset, y, contentHeight) + leftOffset; - } - - if (mExpandedActionView == null) { - final boolean showTitle = mTitleLayout != null && mTitleLayout.getVisibility() != GONE && - (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0; - if (showTitle) { - x += positionChild(mTitleLayout, x, y, contentHeight); - } - - switch (mNavigationMode) { - case ActionBar.NAVIGATION_MODE_STANDARD: - break; - case ActionBar.NAVIGATION_MODE_LIST: - if (mListNavLayout != null) { - if (showTitle) x += mItemPadding; - x += positionChild(mListNavLayout, x, y, contentHeight) + mItemPadding; - } - break; - case ActionBar.NAVIGATION_MODE_TABS: - if (mTabScrollView != null) { - if (showTitle) x += mItemPadding; - x += positionChild(mTabScrollView, x, y, contentHeight) + mItemPadding; - } - break; - } - } - - int menuLeft = r - l - getPaddingRight(); - if (mMenuView != null && mMenuView.getParent() == this) { - positionChildInverse(mMenuView, menuLeft, y, contentHeight); - menuLeft -= mMenuView.getMeasuredWidth(); - } - - if (mIndeterminateProgressView != null && - mIndeterminateProgressView.getVisibility() != GONE) { - positionChildInverse(mIndeterminateProgressView, menuLeft, y, contentHeight); - menuLeft -= mIndeterminateProgressView.getMeasuredWidth(); - } - - View customView = null; - if (mExpandedActionView != null) { - customView = mExpandedActionView; - } else if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0 && - mCustomNavView != null) { - customView = mCustomNavView; - } - if (customView != null) { - ViewGroup.LayoutParams lp = customView.getLayoutParams(); - final ActionBar.LayoutParams ablp = lp instanceof ActionBar.LayoutParams ? - (ActionBar.LayoutParams) lp : null; - - final int gravity = ablp != null ? ablp.gravity : DEFAULT_CUSTOM_GRAVITY; - final int navWidth = customView.getMeasuredWidth(); - - int topMargin = 0; - int bottomMargin = 0; - if (ablp != null) { - x += ablp.leftMargin; - menuLeft -= ablp.rightMargin; - topMargin = ablp.topMargin; - bottomMargin = ablp.bottomMargin; - } - - int hgravity = gravity & Gravity.HORIZONTAL_GRAVITY_MASK; - // See if we actually have room to truly center; if not push against left or right. - if (hgravity == Gravity.CENTER_HORIZONTAL) { - final int centeredLeft = ((getRight() - getLeft()) - navWidth) / 2; - if (centeredLeft < x) { - hgravity = Gravity.LEFT; - } else if (centeredLeft + navWidth > menuLeft) { - hgravity = Gravity.RIGHT; - } - } else if (gravity == -1) { - hgravity = Gravity.LEFT; - } - - int xpos = 0; - switch (hgravity) { - case Gravity.CENTER_HORIZONTAL: - xpos = ((getRight() - getLeft()) - navWidth) / 2; - break; - case Gravity.LEFT: - xpos = x; - break; - case Gravity.RIGHT: - xpos = menuLeft - navWidth; - break; - } - - int vgravity = gravity & Gravity.VERTICAL_GRAVITY_MASK; - - if (gravity == -1) { - vgravity = Gravity.CENTER_VERTICAL; - } - - int ypos = 0; - switch (vgravity) { - case Gravity.CENTER_VERTICAL: - final int paddedTop = getPaddingTop(); - final int paddedBottom = getBottom() - getTop() - getPaddingBottom(); - ypos = ((paddedBottom - paddedTop) - customView.getMeasuredHeight()) / 2; - break; - case Gravity.TOP: - ypos = getPaddingTop() + topMargin; - break; - case Gravity.BOTTOM: - ypos = getHeight() - getPaddingBottom() - customView.getMeasuredHeight() - - bottomMargin; - break; - } - final int customWidth = customView.getMeasuredWidth(); - customView.layout(xpos, ypos, xpos + customWidth, - ypos + customView.getMeasuredHeight()); - x += customWidth; - } - - if (mProgressView != null) { - mProgressView.bringToFront(); - final int halfProgressHeight = mProgressView.getMeasuredHeight() / 2; - mProgressView.layout(mProgressBarPadding, -halfProgressHeight, - mProgressBarPadding + mProgressView.getMeasuredWidth(), halfProgressHeight); - } - } - - @Override - public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) { - return new ActionBar.LayoutParams(getContext(), attrs); - } - - @Override - public ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams lp) { - if (lp == null) { - lp = generateDefaultLayoutParams(); - } - return lp; - } - - @Override - public Parcelable onSaveInstanceState() { - Parcelable superState = super.onSaveInstanceState(); - SavedState state = new SavedState(superState); - - if (mExpandedMenuPresenter != null && mExpandedMenuPresenter.mCurrentExpandedItem != null) { - state.expandedMenuItemId = mExpandedMenuPresenter.mCurrentExpandedItem.getItemId(); - } - - state.isOverflowOpen = isOverflowMenuShowing(); - - return state; - } - - @Override - public void onRestoreInstanceState(Parcelable p) { - SavedState state = (SavedState) p; - - super.onRestoreInstanceState(state.getSuperState()); - - if (state.expandedMenuItemId != 0 && - mExpandedMenuPresenter != null && mOptionsMenu != null) { - final MenuItem item = mOptionsMenu.findItem(state.expandedMenuItemId); - if (item != null) { - item.expandActionView(); - } - } - - if (state.isOverflowOpen) { - postShowOverflowMenu(); - } - } - - static class SavedState extends BaseSavedState { - int expandedMenuItemId; - boolean isOverflowOpen; - - SavedState(Parcelable superState) { - super(superState); - } - - private SavedState(Parcel in) { - super(in); - expandedMenuItemId = in.readInt(); - isOverflowOpen = in.readInt() != 0; - } - - @Override - public void writeToParcel(Parcel out, int flags) { - super.writeToParcel(out, flags); - out.writeInt(expandedMenuItemId); - out.writeInt(isOverflowOpen ? 1 : 0); - } - - public static final Parcelable.Creator CREATOR = - new Parcelable.Creator() { - public SavedState createFromParcel(Parcel in) { - return new SavedState(in); - } - - public SavedState[] newArray(int size) { - return new SavedState[size]; - } - }; - } - - public static class HomeView extends FrameLayout { - private View mUpView; - private ImageView mIconView; - private int mUpWidth; - - public HomeView(Context context) { - this(context, null); - } - - public HomeView(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public void setUp(boolean isUp) { - mUpView.setVisibility(isUp ? VISIBLE : GONE); - } - - public void setIcon(Drawable icon) { - mIconView.setImageDrawable(icon); - } - - @Override - public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { - onPopulateAccessibilityEvent(event); - return true; - } - - @Override - public void onPopulateAccessibilityEvent(AccessibilityEvent event) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { - super.onPopulateAccessibilityEvent(event); - } - final CharSequence cdesc = getContentDescription(); - if (!TextUtils.isEmpty(cdesc)) { - event.getText().add(cdesc); - } - } - - @Override - public boolean dispatchHoverEvent(MotionEvent event) { - // Don't allow children to hover; we want this to be treated as a single component. - return onHoverEvent(event); - } - - @Override - protected void onFinishInflate() { - mUpView = findViewById(R.id.abs__up); - mIconView = (ImageView) findViewById(R.id.abs__home); - } - - public int getLeftOffset() { - return mUpView.getVisibility() == GONE ? mUpWidth : 0; - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - measureChildWithMargins(mUpView, widthMeasureSpec, 0, heightMeasureSpec, 0); - final LayoutParams upLp = (LayoutParams) mUpView.getLayoutParams(); - mUpWidth = upLp.leftMargin + mUpView.getMeasuredWidth() + upLp.rightMargin; - int width = mUpView.getVisibility() == GONE ? 0 : mUpWidth; - int height = upLp.topMargin + mUpView.getMeasuredHeight() + upLp.bottomMargin; - measureChildWithMargins(mIconView, widthMeasureSpec, width, heightMeasureSpec, 0); - final LayoutParams iconLp = (LayoutParams) mIconView.getLayoutParams(); - width += iconLp.leftMargin + mIconView.getMeasuredWidth() + iconLp.rightMargin; - height = Math.max(height, - iconLp.topMargin + mIconView.getMeasuredHeight() + iconLp.bottomMargin); - - final int widthMode = MeasureSpec.getMode(widthMeasureSpec); - final int heightMode = MeasureSpec.getMode(heightMeasureSpec); - final int widthSize = MeasureSpec.getSize(widthMeasureSpec); - final int heightSize = MeasureSpec.getSize(heightMeasureSpec); - - switch (widthMode) { - case MeasureSpec.AT_MOST: - width = Math.min(width, widthSize); - break; - case MeasureSpec.EXACTLY: - width = widthSize; - break; - case MeasureSpec.UNSPECIFIED: - default: - break; - } - switch (heightMode) { - case MeasureSpec.AT_MOST: - height = Math.min(height, heightSize); - break; - case MeasureSpec.EXACTLY: - height = heightSize; - break; - case MeasureSpec.UNSPECIFIED: - default: - break; - } - setMeasuredDimension(width, height); - } - - @Override - protected void onLayout(boolean changed, int l, int t, int r, int b) { - final int vCenter = (b - t) / 2; - //UNUSED int width = r - l; - int upOffset = 0; - if (mUpView.getVisibility() != GONE) { - final LayoutParams upLp = (LayoutParams) mUpView.getLayoutParams(); - final int upHeight = mUpView.getMeasuredHeight(); - final int upWidth = mUpView.getMeasuredWidth(); - final int upTop = vCenter - upHeight / 2; - mUpView.layout(0, upTop, upWidth, upTop + upHeight); - upOffset = upLp.leftMargin + upWidth + upLp.rightMargin; - //UNUSED width -= upOffset; - l += upOffset; - } - final LayoutParams iconLp = (LayoutParams) mIconView.getLayoutParams(); - final int iconHeight = mIconView.getMeasuredHeight(); - final int iconWidth = mIconView.getMeasuredWidth(); - final int hCenter = (r - l) / 2; - final int iconLeft = upOffset + Math.max(iconLp.leftMargin, hCenter - iconWidth / 2); - final int iconTop = Math.max(iconLp.topMargin, vCenter - iconHeight / 2); - mIconView.layout(iconLeft, iconTop, iconLeft + iconWidth, iconTop + iconHeight); - } - } - - private class ExpandedActionViewMenuPresenter implements MenuPresenter { - MenuBuilder mMenu; - MenuItemImpl mCurrentExpandedItem; - - @Override - public void initForMenu(Context context, MenuBuilder menu) { - // Clear the expanded action view when menus change. - if (mMenu != null && mCurrentExpandedItem != null) { - mMenu.collapseItemActionView(mCurrentExpandedItem); - } - mMenu = menu; - } - - @Override - public MenuView getMenuView(ViewGroup root) { - return null; - } - - @Override - public void updateMenuView(boolean cleared) { - // Make sure the expanded item we have is still there. - if (mCurrentExpandedItem != null) { - boolean found = false; - - if (mMenu != null) { - final int count = mMenu.size(); - for (int i = 0; i < count; i++) { - final MenuItem item = mMenu.getItem(i); - if (item == mCurrentExpandedItem) { - found = true; - break; - } - } - } - - if (!found) { - // The item we had expanded disappeared. Collapse. - collapseItemActionView(mMenu, mCurrentExpandedItem); - } - } - } - - @Override - public void setCallback(Callback cb) { - } - - @Override - public boolean onSubMenuSelected(SubMenuBuilder subMenu) { - return false; - } - - @Override - public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) { - } - - @Override - public boolean flagActionItems() { - return false; - } - - @Override - public boolean expandItemActionView(MenuBuilder menu, MenuItemImpl item) { - mExpandedActionView = item.getActionView(); - mExpandedHomeLayout.setIcon(mIcon.getConstantState().newDrawable(/* TODO getResources() */)); - mCurrentExpandedItem = item; - if (mExpandedActionView.getParent() != ActionBarView.this) { - addView(mExpandedActionView); - } - if (mExpandedHomeLayout.getParent() != ActionBarView.this) { - addView(mExpandedHomeLayout); - } - mHomeLayout.setVisibility(GONE); - if (mTitleLayout != null) mTitleLayout.setVisibility(GONE); - if (mTabScrollView != null) mTabScrollView.setVisibility(GONE); - if (mSpinner != null) mSpinner.setVisibility(GONE); - if (mCustomNavView != null) mCustomNavView.setVisibility(GONE); - requestLayout(); - item.setActionViewExpanded(true); - - if (mExpandedActionView instanceof CollapsibleActionView) { - ((CollapsibleActionView) mExpandedActionView).onActionViewExpanded(); - } - - return true; - } - - @Override - public boolean collapseItemActionView(MenuBuilder menu, MenuItemImpl item) { - // Do this before detaching the actionview from the hierarchy, in case - // it needs to dismiss the soft keyboard, etc. - if (mExpandedActionView instanceof CollapsibleActionView) { - ((CollapsibleActionView) mExpandedActionView).onActionViewCollapsed(); - } - - removeView(mExpandedActionView); - removeView(mExpandedHomeLayout); - mExpandedActionView = null; - if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_HOME) != 0) { - mHomeLayout.setVisibility(VISIBLE); - } - if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0) { - if (mTitleLayout == null) { - initTitle(); - } else { - mTitleLayout.setVisibility(VISIBLE); - } - } - if (mTabScrollView != null && mNavigationMode == ActionBar.NAVIGATION_MODE_TABS) { - mTabScrollView.setVisibility(VISIBLE); - } - if (mSpinner != null && mNavigationMode == ActionBar.NAVIGATION_MODE_LIST) { - mSpinner.setVisibility(VISIBLE); - } - if (mCustomNavView != null && (mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0) { - mCustomNavView.setVisibility(VISIBLE); - } - mExpandedHomeLayout.setIcon(null); - mCurrentExpandedItem = null; - requestLayout(); - item.setActionViewExpanded(false); - - return true; - } - - @Override - public int getId() { - return 0; - } - - @Override - public Parcelable onSaveInstanceState() { - return null; - } - - @Override - public void onRestoreInstanceState(Parcelable state) { - } - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/CapitalizingButton.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/CapitalizingButton.java deleted file mode 100644 index fa3698f3b..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/CapitalizingButton.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.actionbarsherlock.internal.widget; - -import java.util.Locale; -import android.content.Context; -import android.content.res.TypedArray; -import android.os.Build; -import android.util.AttributeSet; -import android.widget.Button; - -public class CapitalizingButton extends Button { - private static final boolean SANS_ICE_CREAM = Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH; - private static final boolean IS_GINGERBREAD = Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD; - - private static final int[] R_styleable_Button = new int[] { - android.R.attr.textAllCaps - }; - private static final int R_styleable_Button_textAllCaps = 0; - - private boolean mAllCaps; - - public CapitalizingButton(Context context, AttributeSet attrs) { - super(context, attrs); - - TypedArray a = context.obtainStyledAttributes(attrs, R_styleable_Button); - mAllCaps = a.getBoolean(R_styleable_Button_textAllCaps, true); - a.recycle(); - } - - public void setTextCompat(CharSequence text) { - if (SANS_ICE_CREAM && mAllCaps && text != null) { - if (IS_GINGERBREAD) { - setText(text.toString().toUpperCase(Locale.ROOT)); - } else { - setText(text.toString().toUpperCase()); - } - } else { - setText(text); - } - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/CapitalizingTextView.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/CapitalizingTextView.java deleted file mode 100644 index 673ec554f..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/CapitalizingTextView.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.actionbarsherlock.internal.widget; - -import java.util.Locale; -import android.content.Context; -import android.content.res.TypedArray; -import android.os.Build; -import android.util.AttributeSet; -import android.widget.TextView; - -public class CapitalizingTextView extends TextView { - private static final boolean SANS_ICE_CREAM = Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH; - private static final boolean IS_GINGERBREAD = Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD; - - private static final int[] R_styleable_TextView = new int[] { - android.R.attr.textAllCaps - }; - private static final int R_styleable_TextView_textAllCaps = 0; - - private boolean mAllCaps; - - public CapitalizingTextView(Context context, AttributeSet attrs) { - this(context, attrs, 0); - } - - public CapitalizingTextView(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - - TypedArray a = context.obtainStyledAttributes(attrs, R_styleable_TextView, defStyle, 0); - mAllCaps = a.getBoolean(R_styleable_TextView_textAllCaps, true); - a.recycle(); - } - - public void setTextCompat(CharSequence text) { - if (SANS_ICE_CREAM && mAllCaps && text != null) { - if (IS_GINGERBREAD) { - setText(text.toString().toUpperCase(Locale.ROOT)); - } else { - setText(text.toString().toUpperCase()); - } - } else { - setText(text); - } - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/FakeDialogPhoneWindow.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/FakeDialogPhoneWindow.java deleted file mode 100644 index ad1b4f0a8..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/FakeDialogPhoneWindow.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.actionbarsherlock.internal.widget; - -import static android.view.View.MeasureSpec.EXACTLY; -import android.content.Context; -import android.content.res.TypedArray; -import android.util.AttributeSet; -import android.util.DisplayMetrics; -import android.util.TypedValue; -import android.widget.LinearLayout; -import com.actionbarsherlock.R; - -public class FakeDialogPhoneWindow extends LinearLayout { - final TypedValue mMinWidthMajor = new TypedValue(); - final TypedValue mMinWidthMinor = new TypedValue(); - - public FakeDialogPhoneWindow(Context context, AttributeSet attrs) { - super(context, attrs); - - TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SherlockTheme); - - a.getValue(R.styleable.SherlockTheme_windowMinWidthMajor, mMinWidthMajor); - a.getValue(R.styleable.SherlockTheme_windowMinWidthMinor, mMinWidthMinor); - - a.recycle(); - } - - /* Stolen from PhoneWindow */ - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - final DisplayMetrics metrics = getContext().getResources().getDisplayMetrics(); - final boolean isPortrait = metrics.widthPixels < metrics.heightPixels; - - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - - int width = getMeasuredWidth(); - boolean measure = false; - - widthMeasureSpec = MeasureSpec.makeMeasureSpec(width, EXACTLY); - - final TypedValue tv = isPortrait ? mMinWidthMinor : mMinWidthMajor; - - if (tv.type != TypedValue.TYPE_NULL) { - final int min; - if (tv.type == TypedValue.TYPE_DIMENSION) { - min = (int)tv.getDimension(metrics); - } else if (tv.type == TypedValue.TYPE_FRACTION) { - min = (int)tv.getFraction(metrics.widthPixels, metrics.widthPixels); - } else { - min = 0; - } - - if (width < min) { - widthMeasureSpec = MeasureSpec.makeMeasureSpec(min, EXACTLY); - measure = true; - } - } - - // TODO: Support height? - - if (measure) { - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - } - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/IcsAbsSpinner.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/IcsAbsSpinner.java deleted file mode 100644 index ce0cb3bca..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/IcsAbsSpinner.java +++ /dev/null @@ -1,479 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.widget; - -import android.content.Context; -import android.database.DataSetObserver; -import android.graphics.Rect; -import android.os.Build; -import android.os.Parcel; -import android.os.Parcelable; -import android.util.AttributeSet; -import android.util.SparseArray; -import android.view.View; -import android.view.ViewGroup; -import android.widget.SpinnerAdapter; - -/** - * An abstract base class for spinner widgets. SDK users will probably not - * need to use this class. - * - * @attr ref android.R.styleable#AbsSpinner_entries - */ -public abstract class IcsAbsSpinner extends IcsAdapterView { - private static final boolean IS_HONEYCOMB = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB; - - SpinnerAdapter mAdapter; - - int mHeightMeasureSpec; - int mWidthMeasureSpec; - boolean mBlockLayoutRequests; - - int mSelectionLeftPadding = 0; - int mSelectionTopPadding = 0; - int mSelectionRightPadding = 0; - int mSelectionBottomPadding = 0; - final Rect mSpinnerPadding = new Rect(); - - final RecycleBin mRecycler = new RecycleBin(); - private DataSetObserver mDataSetObserver; - - /** Temporary frame to hold a child View's frame rectangle */ - private Rect mTouchFrame; - - public IcsAbsSpinner(Context context) { - super(context); - initAbsSpinner(); - } - - public IcsAbsSpinner(Context context, AttributeSet attrs) { - this(context, attrs, 0); - } - - public IcsAbsSpinner(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - initAbsSpinner(); - - /* - TypedArray a = context.obtainStyledAttributes(attrs, - com.android.internal.R.styleable.AbsSpinner, defStyle, 0); - - CharSequence[] entries = a.getTextArray(R.styleable.AbsSpinner_entries); - if (entries != null) { - ArrayAdapter adapter = - new ArrayAdapter(context, - R.layout.simple_spinner_item, entries); - adapter.setDropDownViewResource(R.layout.simple_spinner_dropdown_item); - setAdapter(adapter); - } - - a.recycle(); - */ - } - - /** - * Common code for different constructor flavors - */ - private void initAbsSpinner() { - setFocusable(true); - setWillNotDraw(false); - } - - /** - * The Adapter is used to provide the data which backs this Spinner. - * It also provides methods to transform spinner items based on their position - * relative to the selected item. - * @param adapter The SpinnerAdapter to use for this Spinner - */ - @Override - public void setAdapter(SpinnerAdapter adapter) { - if (null != mAdapter) { - mAdapter.unregisterDataSetObserver(mDataSetObserver); - resetList(); - } - - mAdapter = adapter; - - mOldSelectedPosition = INVALID_POSITION; - mOldSelectedRowId = INVALID_ROW_ID; - - if (mAdapter != null) { - mOldItemCount = mItemCount; - mItemCount = mAdapter.getCount(); - checkFocus(); - - mDataSetObserver = new AdapterDataSetObserver(); - mAdapter.registerDataSetObserver(mDataSetObserver); - - int position = mItemCount > 0 ? 0 : INVALID_POSITION; - - setSelectedPositionInt(position); - setNextSelectedPositionInt(position); - - if (mItemCount == 0) { - // Nothing selected - checkSelectionChanged(); - } - - } else { - checkFocus(); - resetList(); - // Nothing selected - checkSelectionChanged(); - } - - requestLayout(); - } - - /** - * Clear out all children from the list - */ - void resetList() { - mDataChanged = false; - mNeedSync = false; - - removeAllViewsInLayout(); - mOldSelectedPosition = INVALID_POSITION; - mOldSelectedRowId = INVALID_ROW_ID; - - setSelectedPositionInt(INVALID_POSITION); - setNextSelectedPositionInt(INVALID_POSITION); - invalidate(); - } - - /** - * @see android.view.View#measure(int, int) - * - * Figure out the dimensions of this Spinner. The width comes from - * the widthMeasureSpec as Spinnners can't have their width set to - * UNSPECIFIED. The height is based on the height of the selected item - * plus padding. - */ - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - int widthMode = MeasureSpec.getMode(widthMeasureSpec); - int widthSize; - int heightSize; - - final int mPaddingLeft = getPaddingLeft(); - final int mPaddingTop = getPaddingTop(); - final int mPaddingRight = getPaddingRight(); - final int mPaddingBottom = getPaddingBottom(); - - mSpinnerPadding.left = mPaddingLeft > mSelectionLeftPadding ? mPaddingLeft - : mSelectionLeftPadding; - mSpinnerPadding.top = mPaddingTop > mSelectionTopPadding ? mPaddingTop - : mSelectionTopPadding; - mSpinnerPadding.right = mPaddingRight > mSelectionRightPadding ? mPaddingRight - : mSelectionRightPadding; - mSpinnerPadding.bottom = mPaddingBottom > mSelectionBottomPadding ? mPaddingBottom - : mSelectionBottomPadding; - - if (mDataChanged) { - handleDataChanged(); - } - - int preferredHeight = 0; - int preferredWidth = 0; - boolean needsMeasuring = true; - - int selectedPosition = getSelectedItemPosition(); - if (selectedPosition >= 0 && mAdapter != null && selectedPosition < mAdapter.getCount()) { - // Try looking in the recycler. (Maybe we were measured once already) - View view = mRecycler.get(selectedPosition); - if (view == null) { - // Make a new one - view = mAdapter.getView(selectedPosition, null, this); - } - - if (view != null) { - // Put in recycler for re-measuring and/or layout - mRecycler.put(selectedPosition, view); - } - - if (view != null) { - if (view.getLayoutParams() == null) { - mBlockLayoutRequests = true; - view.setLayoutParams(generateDefaultLayoutParams()); - mBlockLayoutRequests = false; - } - measureChild(view, widthMeasureSpec, heightMeasureSpec); - - preferredHeight = getChildHeight(view) + mSpinnerPadding.top + mSpinnerPadding.bottom; - preferredWidth = getChildWidth(view) + mSpinnerPadding.left + mSpinnerPadding.right; - - needsMeasuring = false; - } - } - - if (needsMeasuring) { - // No views -- just use padding - preferredHeight = mSpinnerPadding.top + mSpinnerPadding.bottom; - if (widthMode == MeasureSpec.UNSPECIFIED) { - preferredWidth = mSpinnerPadding.left + mSpinnerPadding.right; - } - } - - preferredHeight = Math.max(preferredHeight, getSuggestedMinimumHeight()); - preferredWidth = Math.max(preferredWidth, getSuggestedMinimumWidth()); - - if (IS_HONEYCOMB) { - heightSize = resolveSizeAndState(preferredHeight, heightMeasureSpec, 0); - widthSize = resolveSizeAndState(preferredWidth, widthMeasureSpec, 0); - } else { - heightSize = resolveSize(preferredHeight, heightMeasureSpec); - widthSize = resolveSize(preferredWidth, widthMeasureSpec); - } - - setMeasuredDimension(widthSize, heightSize); - mHeightMeasureSpec = heightMeasureSpec; - mWidthMeasureSpec = widthMeasureSpec; - } - - int getChildHeight(View child) { - return child.getMeasuredHeight(); - } - - int getChildWidth(View child) { - return child.getMeasuredWidth(); - } - - @Override - protected ViewGroup.LayoutParams generateDefaultLayoutParams() { - return new ViewGroup.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.WRAP_CONTENT); - } - - void recycleAllViews() { - final int childCount = getChildCount(); - final IcsAbsSpinner.RecycleBin recycleBin = mRecycler; - final int position = mFirstPosition; - - // All views go in recycler - for (int i = 0; i < childCount; i++) { - View v = getChildAt(i); - int index = position + i; - recycleBin.put(index, v); - } - } - - /** - * Jump directly to a specific item in the adapter data. - */ - public void setSelection(int position, boolean animate) { - // Animate only if requested position is already on screen somewhere - boolean shouldAnimate = animate && mFirstPosition <= position && - position <= mFirstPosition + getChildCount() - 1; - setSelectionInt(position, shouldAnimate); - } - - @Override - public void setSelection(int position) { - setNextSelectedPositionInt(position); - requestLayout(); - invalidate(); - } - - - /** - * Makes the item at the supplied position selected. - * - * @param position Position to select - * @param animate Should the transition be animated - * - */ - void setSelectionInt(int position, boolean animate) { - if (position != mOldSelectedPosition) { - mBlockLayoutRequests = true; - int delta = position - mSelectedPosition; - setNextSelectedPositionInt(position); - layout(delta, animate); - mBlockLayoutRequests = false; - } - } - - abstract void layout(int delta, boolean animate); - - @Override - public View getSelectedView() { - if (mItemCount > 0 && mSelectedPosition >= 0) { - return getChildAt(mSelectedPosition - mFirstPosition); - } else { - return null; - } - } - - /** - * Override to prevent spamming ourselves with layout requests - * as we place views - * - * @see android.view.View#requestLayout() - */ - @Override - public void requestLayout() { - if (!mBlockLayoutRequests) { - super.requestLayout(); - } - } - - @Override - public SpinnerAdapter getAdapter() { - return mAdapter; - } - - @Override - public int getCount() { - return mItemCount; - } - - /** - * Maps a point to a position in the list. - * - * @param x X in local coordinate - * @param y Y in local coordinate - * @return The position of the item which contains the specified point, or - * {@link #INVALID_POSITION} if the point does not intersect an item. - */ - public int pointToPosition(int x, int y) { - Rect frame = mTouchFrame; - if (frame == null) { - mTouchFrame = new Rect(); - frame = mTouchFrame; - } - - final int count = getChildCount(); - for (int i = count - 1; i >= 0; i--) { - View child = getChildAt(i); - if (child.getVisibility() == View.VISIBLE) { - child.getHitRect(frame); - if (frame.contains(x, y)) { - return mFirstPosition + i; - } - } - } - return INVALID_POSITION; - } - - static class SavedState extends BaseSavedState { - long selectedId; - int position; - - /** - * Constructor called from {@link AbsSpinner#onSaveInstanceState()} - */ - SavedState(Parcelable superState) { - super(superState); - } - - /** - * Constructor called from {@link #CREATOR} - */ - private SavedState(Parcel in) { - super(in); - selectedId = in.readLong(); - position = in.readInt(); - } - - @Override - public void writeToParcel(Parcel out, int flags) { - super.writeToParcel(out, flags); - out.writeLong(selectedId); - out.writeInt(position); - } - - @Override - public String toString() { - return "AbsSpinner.SavedState{" - + Integer.toHexString(System.identityHashCode(this)) - + " selectedId=" + selectedId - + " position=" + position + "}"; - } - - public static final Parcelable.Creator CREATOR - = new Parcelable.Creator() { - public SavedState createFromParcel(Parcel in) { - return new SavedState(in); - } - - public SavedState[] newArray(int size) { - return new SavedState[size]; - } - }; - } - - @Override - public Parcelable onSaveInstanceState() { - Parcelable superState = super.onSaveInstanceState(); - SavedState ss = new SavedState(superState); - ss.selectedId = getSelectedItemId(); - if (ss.selectedId >= 0) { - ss.position = getSelectedItemPosition(); - } else { - ss.position = INVALID_POSITION; - } - return ss; - } - - @Override - public void onRestoreInstanceState(Parcelable state) { - SavedState ss = (SavedState) state; - - super.onRestoreInstanceState(ss.getSuperState()); - - if (ss.selectedId >= 0) { - mDataChanged = true; - mNeedSync = true; - mSyncRowId = ss.selectedId; - mSyncPosition = ss.position; - mSyncMode = SYNC_SELECTED_POSITION; - requestLayout(); - } - } - - class RecycleBin { - private final SparseArray mScrapHeap = new SparseArray(); - - public void put(int position, View v) { - mScrapHeap.put(position, v); - } - - View get(int position) { - // System.out.print("Looking for " + position); - View result = mScrapHeap.get(position); - if (result != null) { - // System.out.println(" HIT"); - mScrapHeap.delete(position); - } else { - // System.out.println(" MISS"); - } - return result; - } - - void clear() { - final SparseArray scrapHeap = mScrapHeap; - final int count = scrapHeap.size(); - for (int i = 0; i < count; i++) { - final View view = scrapHeap.valueAt(i); - if (view != null) { - removeDetachedView(view, true); - } - } - scrapHeap.clear(); - } - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/IcsAdapterView.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/IcsAdapterView.java deleted file mode 100644 index c786dc5c1..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/IcsAdapterView.java +++ /dev/null @@ -1,1160 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.widget; - -import android.content.Context; -import android.database.DataSetObserver; -import android.os.Parcelable; -import android.os.SystemClock; -import android.util.AttributeSet; -import android.util.SparseArray; -import android.view.ContextMenu; -import android.view.SoundEffectConstants; -import android.view.View; -import android.view.ViewDebug; -import android.view.ViewGroup; -import android.view.accessibility.AccessibilityEvent; -import android.view.accessibility.AccessibilityNodeInfo; -import android.widget.Adapter; -import android.widget.AdapterView.OnItemClickListener; -import android.widget.ListView; - - -/** - * An AdapterView is a view whose children are determined by an {@link Adapter}. - * - *

- * See {@link ListView}, {@link GridView}, {@link Spinner} and - * {@link Gallery} for commonly used subclasses of AdapterView. - * - *

- *

Developer Guides

- *

For more information about using AdapterView, read the - * Binding to Data with AdapterView - * developer guide.

- */ -public abstract class IcsAdapterView extends ViewGroup { - - /** - * The item view type returned by {@link Adapter#getItemViewType(int)} when - * the adapter does not want the item's view recycled. - */ - public static final int ITEM_VIEW_TYPE_IGNORE = -1; - - /** - * The item view type returned by {@link Adapter#getItemViewType(int)} when - * the item is a header or footer. - */ - public static final int ITEM_VIEW_TYPE_HEADER_OR_FOOTER = -2; - - /** - * The position of the first child displayed - */ - @ViewDebug.ExportedProperty(category = "scrolling") - int mFirstPosition = 0; - - /** - * The offset in pixels from the top of the AdapterView to the top - * of the view to select during the next layout. - */ - int mSpecificTop; - - /** - * Position from which to start looking for mSyncRowId - */ - int mSyncPosition; - - /** - * Row id to look for when data has changed - */ - long mSyncRowId = INVALID_ROW_ID; - - /** - * Height of the view when mSyncPosition and mSyncRowId where set - */ - long mSyncHeight; - - /** - * True if we need to sync to mSyncRowId - */ - boolean mNeedSync = false; - - /** - * Indicates whether to sync based on the selection or position. Possible - * values are {@link #SYNC_SELECTED_POSITION} or - * {@link #SYNC_FIRST_POSITION}. - */ - int mSyncMode; - - /** - * Our height after the last layout - */ - private int mLayoutHeight; - - /** - * Sync based on the selected child - */ - static final int SYNC_SELECTED_POSITION = 0; - - /** - * Sync based on the first child displayed - */ - static final int SYNC_FIRST_POSITION = 1; - - /** - * Maximum amount of time to spend in {@link #findSyncPosition()} - */ - static final int SYNC_MAX_DURATION_MILLIS = 100; - - /** - * Indicates that this view is currently being laid out. - */ - boolean mInLayout = false; - - /** - * The listener that receives notifications when an item is selected. - */ - OnItemSelectedListener mOnItemSelectedListener; - - /** - * The listener that receives notifications when an item is clicked. - */ - OnItemClickListener mOnItemClickListener; - - /** - * The listener that receives notifications when an item is long clicked. - */ - OnItemLongClickListener mOnItemLongClickListener; - - /** - * True if the data has changed since the last layout - */ - boolean mDataChanged; - - /** - * The position within the adapter's data set of the item to select - * during the next layout. - */ - @ViewDebug.ExportedProperty(category = "list") - int mNextSelectedPosition = INVALID_POSITION; - - /** - * The item id of the item to select during the next layout. - */ - long mNextSelectedRowId = INVALID_ROW_ID; - - /** - * The position within the adapter's data set of the currently selected item. - */ - @ViewDebug.ExportedProperty(category = "list") - int mSelectedPosition = INVALID_POSITION; - - /** - * The item id of the currently selected item. - */ - long mSelectedRowId = INVALID_ROW_ID; - - /** - * View to show if there are no items to show. - */ - private View mEmptyView; - - /** - * The number of items in the current adapter. - */ - @ViewDebug.ExportedProperty(category = "list") - int mItemCount; - - /** - * The number of items in the adapter before a data changed event occurred. - */ - int mOldItemCount; - - /** - * Represents an invalid position. All valid positions are in the range 0 to 1 less than the - * number of items in the current adapter. - */ - public static final int INVALID_POSITION = -1; - - /** - * Represents an empty or invalid row id - */ - public static final long INVALID_ROW_ID = Long.MIN_VALUE; - - /** - * The last selected position we used when notifying - */ - int mOldSelectedPosition = INVALID_POSITION; - - /** - * The id of the last selected position we used when notifying - */ - long mOldSelectedRowId = INVALID_ROW_ID; - - /** - * Indicates what focusable state is requested when calling setFocusable(). - * In addition to this, this view has other criteria for actually - * determining the focusable state (such as whether its empty or the text - * filter is shown). - * - * @see #setFocusable(boolean) - * @see #checkFocus() - */ - private boolean mDesiredFocusableState; - private boolean mDesiredFocusableInTouchModeState; - - private SelectionNotifier mSelectionNotifier; - /** - * When set to true, calls to requestLayout() will not propagate up the parent hierarchy. - * This is used to layout the children during a layout pass. - */ - boolean mBlockLayoutRequests = false; - - public IcsAdapterView(Context context) { - super(context); - } - - public IcsAdapterView(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public IcsAdapterView(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - } - - /** - * Register a callback to be invoked when an item in this AdapterView has - * been clicked. - * - * @param listener The callback that will be invoked. - */ - public void setOnItemClickListener(OnItemClickListener listener) { - mOnItemClickListener = listener; - } - - /** - * @return The callback to be invoked with an item in this AdapterView has - * been clicked, or null id no callback has been set. - */ - public final OnItemClickListener getOnItemClickListener() { - return mOnItemClickListener; - } - - /** - * Call the OnItemClickListener, if it is defined. - * - * @param view The view within the AdapterView that was clicked. - * @param position The position of the view in the adapter. - * @param id The row id of the item that was clicked. - * @return True if there was an assigned OnItemClickListener that was - * called, false otherwise is returned. - */ - public boolean performItemClick(View view, int position, long id) { - if (mOnItemClickListener != null) { - playSoundEffect(SoundEffectConstants.CLICK); - if (view != null) { - view.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED); - } - mOnItemClickListener.onItemClick(/*this*/null, view, position, id); - return true; - } - - return false; - } - - /** - * Interface definition for a callback to be invoked when an item in this - * view has been clicked and held. - */ - public interface OnItemLongClickListener { - /** - * Callback method to be invoked when an item in this view has been - * clicked and held. - * - * Implementers can call getItemAtPosition(position) if they need to access - * the data associated with the selected item. - * - * @param parent The AbsListView where the click happened - * @param view The view within the AbsListView that was clicked - * @param position The position of the view in the list - * @param id The row id of the item that was clicked - * - * @return true if the callback consumed the long click, false otherwise - */ - boolean onItemLongClick(IcsAdapterView parent, View view, int position, long id); - } - - - /** - * Register a callback to be invoked when an item in this AdapterView has - * been clicked and held - * - * @param listener The callback that will run - */ - public void setOnItemLongClickListener(OnItemLongClickListener listener) { - if (!isLongClickable()) { - setLongClickable(true); - } - mOnItemLongClickListener = listener; - } - - /** - * @return The callback to be invoked with an item in this AdapterView has - * been clicked and held, or null id no callback as been set. - */ - public final OnItemLongClickListener getOnItemLongClickListener() { - return mOnItemLongClickListener; - } - - /** - * Interface definition for a callback to be invoked when - * an item in this view has been selected. - */ - public interface OnItemSelectedListener { - /** - *

Callback method to be invoked when an item in this view has been - * selected. This callback is invoked only when the newly selected - * position is different from the previously selected position or if - * there was no selected item.

- * - * Impelmenters can call getItemAtPosition(position) if they need to access the - * data associated with the selected item. - * - * @param parent The AdapterView where the selection happened - * @param view The view within the AdapterView that was clicked - * @param position The position of the view in the adapter - * @param id The row id of the item that is selected - */ - void onItemSelected(IcsAdapterView parent, View view, int position, long id); - - /** - * Callback method to be invoked when the selection disappears from this - * view. The selection can disappear for instance when touch is activated - * or when the adapter becomes empty. - * - * @param parent The AdapterView that now contains no selected item. - */ - void onNothingSelected(IcsAdapterView parent); - } - - - /** - * Register a callback to be invoked when an item in this AdapterView has - * been selected. - * - * @param listener The callback that will run - */ - public void setOnItemSelectedListener(OnItemSelectedListener listener) { - mOnItemSelectedListener = listener; - } - - public final OnItemSelectedListener getOnItemSelectedListener() { - return mOnItemSelectedListener; - } - - /** - * Extra menu information provided to the - * {@link android.view.View.OnCreateContextMenuListener#onCreateContextMenu(ContextMenu, View, ContextMenuInfo) } - * callback when a context menu is brought up for this AdapterView. - * - */ - public static class AdapterContextMenuInfo implements ContextMenu.ContextMenuInfo { - - public AdapterContextMenuInfo(View targetView, int position, long id) { - this.targetView = targetView; - this.position = position; - this.id = id; - } - - /** - * The child view for which the context menu is being displayed. This - * will be one of the children of this AdapterView. - */ - public View targetView; - - /** - * The position in the adapter for which the context menu is being - * displayed. - */ - public int position; - - /** - * The row id of the item for which the context menu is being displayed. - */ - public long id; - } - - /** - * Returns the adapter currently associated with this widget. - * - * @return The adapter used to provide this view's content. - */ - public abstract T getAdapter(); - - /** - * Sets the adapter that provides the data and the views to represent the data - * in this widget. - * - * @param adapter The adapter to use to create this view's content. - */ - public abstract void setAdapter(T adapter); - - /** - * This method is not supported and throws an UnsupportedOperationException when called. - * - * @param child Ignored. - * - * @throws UnsupportedOperationException Every time this method is invoked. - */ - @Override - public void addView(View child) { - throw new UnsupportedOperationException("addView(View) is not supported in AdapterView"); - } - - /** - * This method is not supported and throws an UnsupportedOperationException when called. - * - * @param child Ignored. - * @param index Ignored. - * - * @throws UnsupportedOperationException Every time this method is invoked. - */ - @Override - public void addView(View child, int index) { - throw new UnsupportedOperationException("addView(View, int) is not supported in AdapterView"); - } - - /** - * This method is not supported and throws an UnsupportedOperationException when called. - * - * @param child Ignored. - * @param params Ignored. - * - * @throws UnsupportedOperationException Every time this method is invoked. - */ - @Override - public void addView(View child, LayoutParams params) { - throw new UnsupportedOperationException("addView(View, LayoutParams) " - + "is not supported in AdapterView"); - } - - /** - * This method is not supported and throws an UnsupportedOperationException when called. - * - * @param child Ignored. - * @param index Ignored. - * @param params Ignored. - * - * @throws UnsupportedOperationException Every time this method is invoked. - */ - @Override - public void addView(View child, int index, LayoutParams params) { - throw new UnsupportedOperationException("addView(View, int, LayoutParams) " - + "is not supported in AdapterView"); - } - - /** - * This method is not supported and throws an UnsupportedOperationException when called. - * - * @param child Ignored. - * - * @throws UnsupportedOperationException Every time this method is invoked. - */ - @Override - public void removeView(View child) { - throw new UnsupportedOperationException("removeView(View) is not supported in AdapterView"); - } - - /** - * This method is not supported and throws an UnsupportedOperationException when called. - * - * @param index Ignored. - * - * @throws UnsupportedOperationException Every time this method is invoked. - */ - @Override - public void removeViewAt(int index) { - throw new UnsupportedOperationException("removeViewAt(int) is not supported in AdapterView"); - } - - /** - * This method is not supported and throws an UnsupportedOperationException when called. - * - * @throws UnsupportedOperationException Every time this method is invoked. - */ - @Override - public void removeAllViews() { - throw new UnsupportedOperationException("removeAllViews() is not supported in AdapterView"); - } - - @Override - protected void onLayout(boolean changed, int left, int top, int right, int bottom) { - mLayoutHeight = getHeight(); - } - - /** - * Return the position of the currently selected item within the adapter's data set - * - * @return int Position (starting at 0), or {@link #INVALID_POSITION} if there is nothing selected. - */ - @ViewDebug.CapturedViewProperty - public int getSelectedItemPosition() { - return mNextSelectedPosition; - } - - /** - * @return The id corresponding to the currently selected item, or {@link #INVALID_ROW_ID} - * if nothing is selected. - */ - @ViewDebug.CapturedViewProperty - public long getSelectedItemId() { - return mNextSelectedRowId; - } - - /** - * @return The view corresponding to the currently selected item, or null - * if nothing is selected - */ - public abstract View getSelectedView(); - - /** - * @return The data corresponding to the currently selected item, or - * null if there is nothing selected. - */ - public Object getSelectedItem() { - T adapter = getAdapter(); - int selection = getSelectedItemPosition(); - if (adapter != null && adapter.getCount() > 0 && selection >= 0) { - return adapter.getItem(selection); - } else { - return null; - } - } - - /** - * @return The number of items owned by the Adapter associated with this - * AdapterView. (This is the number of data items, which may be - * larger than the number of visible views.) - */ - @ViewDebug.CapturedViewProperty - public int getCount() { - return mItemCount; - } - - /** - * Get the position within the adapter's data set for the view, where view is a an adapter item - * or a descendant of an adapter item. - * - * @param view an adapter item, or a descendant of an adapter item. This must be visible in this - * AdapterView at the time of the call. - * @return the position within the adapter's data set of the view, or {@link #INVALID_POSITION} - * if the view does not correspond to a list item (or it is not currently visible). - */ - public int getPositionForView(View view) { - View listItem = view; - try { - View v; - while (!(v = (View) listItem.getParent()).equals(this)) { - listItem = v; - } - } catch (ClassCastException e) { - // We made it up to the window without find this list view - return INVALID_POSITION; - } - - // Search the children for the list item - final int childCount = getChildCount(); - for (int i = 0; i < childCount; i++) { - if (getChildAt(i).equals(listItem)) { - return mFirstPosition + i; - } - } - - // Child not found! - return INVALID_POSITION; - } - - /** - * Returns the position within the adapter's data set for the first item - * displayed on screen. - * - * @return The position within the adapter's data set - */ - public int getFirstVisiblePosition() { - return mFirstPosition; - } - - /** - * Returns the position within the adapter's data set for the last item - * displayed on screen. - * - * @return The position within the adapter's data set - */ - public int getLastVisiblePosition() { - return mFirstPosition + getChildCount() - 1; - } - - /** - * Sets the currently selected item. To support accessibility subclasses that - * override this method must invoke the overriden super method first. - * - * @param position Index (starting at 0) of the data item to be selected. - */ - public abstract void setSelection(int position); - - /** - * Sets the view to show if the adapter is empty - */ - public void setEmptyView(View emptyView) { - mEmptyView = emptyView; - - final T adapter = getAdapter(); - final boolean empty = ((adapter == null) || adapter.isEmpty()); - updateEmptyStatus(empty); - } - - /** - * When the current adapter is empty, the AdapterView can display a special view - * call the empty view. The empty view is used to provide feedback to the user - * that no data is available in this AdapterView. - * - * @return The view to show if the adapter is empty. - */ - public View getEmptyView() { - return mEmptyView; - } - - /** - * Indicates whether this view is in filter mode. Filter mode can for instance - * be enabled by a user when typing on the keyboard. - * - * @return True if the view is in filter mode, false otherwise. - */ - boolean isInFilterMode() { - return false; - } - - @Override - public void setFocusable(boolean focusable) { - final T adapter = getAdapter(); - final boolean empty = adapter == null || adapter.getCount() == 0; - - mDesiredFocusableState = focusable; - if (!focusable) { - mDesiredFocusableInTouchModeState = false; - } - - super.setFocusable(focusable && (!empty || isInFilterMode())); - } - - @Override - public void setFocusableInTouchMode(boolean focusable) { - final T adapter = getAdapter(); - final boolean empty = adapter == null || adapter.getCount() == 0; - - mDesiredFocusableInTouchModeState = focusable; - if (focusable) { - mDesiredFocusableState = true; - } - - super.setFocusableInTouchMode(focusable && (!empty || isInFilterMode())); - } - - void checkFocus() { - final T adapter = getAdapter(); - final boolean empty = adapter == null || adapter.getCount() == 0; - final boolean focusable = !empty || isInFilterMode(); - // The order in which we set focusable in touch mode/focusable may matter - // for the client, see View.setFocusableInTouchMode() comments for more - // details - super.setFocusableInTouchMode(focusable && mDesiredFocusableInTouchModeState); - super.setFocusable(focusable && mDesiredFocusableState); - if (mEmptyView != null) { - updateEmptyStatus((adapter == null) || adapter.isEmpty()); - } - } - - /** - * Update the status of the list based on the empty parameter. If empty is true and - * we have an empty view, display it. In all the other cases, make sure that the listview - * is VISIBLE and that the empty view is GONE (if it's not null). - */ - private void updateEmptyStatus(boolean empty) { - if (isInFilterMode()) { - empty = false; - } - - if (empty) { - if (mEmptyView != null) { - mEmptyView.setVisibility(View.VISIBLE); - setVisibility(View.GONE); - } else { - // If the caller just removed our empty view, make sure the list view is visible - setVisibility(View.VISIBLE); - } - - // We are now GONE, so pending layouts will not be dispatched. - // Force one here to make sure that the state of the list matches - // the state of the adapter. - if (mDataChanged) { - this.onLayout(false, getLeft(), getTop(), getRight(), getBottom()); - } - } else { - if (mEmptyView != null) mEmptyView.setVisibility(View.GONE); - setVisibility(View.VISIBLE); - } - } - - /** - * Gets the data associated with the specified position in the list. - * - * @param position Which data to get - * @return The data associated with the specified position in the list - */ - public Object getItemAtPosition(int position) { - T adapter = getAdapter(); - return (adapter == null || position < 0) ? null : adapter.getItem(position); - } - - public long getItemIdAtPosition(int position) { - T adapter = getAdapter(); - return (adapter == null || position < 0) ? INVALID_ROW_ID : adapter.getItemId(position); - } - - @Override - public void setOnClickListener(OnClickListener l) { - throw new RuntimeException("Don't call setOnClickListener for an AdapterView. " - + "You probably want setOnItemClickListener instead"); - } - - /** - * Override to prevent freezing of any views created by the adapter. - */ - @Override - protected void dispatchSaveInstanceState(SparseArray container) { - dispatchFreezeSelfOnly(container); - } - - /** - * Override to prevent thawing of any views created by the adapter. - */ - @Override - protected void dispatchRestoreInstanceState(SparseArray container) { - dispatchThawSelfOnly(container); - } - - class AdapterDataSetObserver extends DataSetObserver { - - private Parcelable mInstanceState = null; - - @Override - public void onChanged() { - mDataChanged = true; - mOldItemCount = mItemCount; - mItemCount = getAdapter().getCount(); - - // Detect the case where a cursor that was previously invalidated has - // been repopulated with new data. - if (IcsAdapterView.this.getAdapter().hasStableIds() && mInstanceState != null - && mOldItemCount == 0 && mItemCount > 0) { - IcsAdapterView.this.onRestoreInstanceState(mInstanceState); - mInstanceState = null; - } else { - rememberSyncState(); - } - checkFocus(); - requestLayout(); - } - - @Override - public void onInvalidated() { - mDataChanged = true; - - if (IcsAdapterView.this.getAdapter().hasStableIds()) { - // Remember the current state for the case where our hosting activity is being - // stopped and later restarted - mInstanceState = IcsAdapterView.this.onSaveInstanceState(); - } - - // Data is invalid so we should reset our state - mOldItemCount = mItemCount; - mItemCount = 0; - mSelectedPosition = INVALID_POSITION; - mSelectedRowId = INVALID_ROW_ID; - mNextSelectedPosition = INVALID_POSITION; - mNextSelectedRowId = INVALID_ROW_ID; - mNeedSync = false; - - checkFocus(); - requestLayout(); - } - - public void clearSavedState() { - mInstanceState = null; - } - } - - @Override - protected void onDetachedFromWindow() { - super.onDetachedFromWindow(); - removeCallbacks(mSelectionNotifier); - } - - private class SelectionNotifier implements Runnable { - public void run() { - if (mDataChanged) { - // Data has changed between when this SelectionNotifier - // was posted and now. We need to wait until the AdapterView - // has been synched to the new data. - if (getAdapter() != null) { - post(this); - } - } else { - fireOnSelected(); - } - } - } - - void selectionChanged() { - if (mOnItemSelectedListener != null) { - if (mInLayout || mBlockLayoutRequests) { - // If we are in a layout traversal, defer notification - // by posting. This ensures that the view tree is - // in a consistent state and is able to accomodate - // new layout or invalidate requests. - if (mSelectionNotifier == null) { - mSelectionNotifier = new SelectionNotifier(); - } - post(mSelectionNotifier); - } else { - fireOnSelected(); - } - } - - // we fire selection events here not in View - if (mSelectedPosition != ListView.INVALID_POSITION && isShown() && !isInTouchMode()) { - sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED); - } - } - - private void fireOnSelected() { - if (mOnItemSelectedListener == null) - return; - - int selection = this.getSelectedItemPosition(); - if (selection >= 0) { - View v = getSelectedView(); - mOnItemSelectedListener.onItemSelected(this, v, selection, - getAdapter().getItemId(selection)); - } else { - mOnItemSelectedListener.onNothingSelected(this); - } - } - - @Override - public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { - View selectedView = getSelectedView(); - if (selectedView != null && selectedView.getVisibility() == VISIBLE - && selectedView.dispatchPopulateAccessibilityEvent(event)) { - return true; - } - return false; - } - - @Override - public boolean onRequestSendAccessibilityEvent(View child, AccessibilityEvent event) { - if (super.onRequestSendAccessibilityEvent(child, event)) { - // Add a record for ourselves as well. - AccessibilityEvent record = AccessibilityEvent.obtain(); - onInitializeAccessibilityEvent(record); - // Populate with the text of the requesting child. - child.dispatchPopulateAccessibilityEvent(record); - event.appendRecord(record); - return true; - } - return false; - } - - @Override - public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { - super.onInitializeAccessibilityNodeInfo(info); - info.setScrollable(isScrollableForAccessibility()); - View selectedView = getSelectedView(); - if (selectedView != null) { - info.setEnabled(selectedView.isEnabled()); - } - } - - @Override - public void onInitializeAccessibilityEvent(AccessibilityEvent event) { - super.onInitializeAccessibilityEvent(event); - event.setScrollable(isScrollableForAccessibility()); - View selectedView = getSelectedView(); - if (selectedView != null) { - event.setEnabled(selectedView.isEnabled()); - } - event.setCurrentItemIndex(getSelectedItemPosition()); - event.setFromIndex(getFirstVisiblePosition()); - event.setToIndex(getLastVisiblePosition()); - event.setItemCount(getCount()); - } - - private boolean isScrollableForAccessibility() { - T adapter = getAdapter(); - if (adapter != null) { - final int itemCount = adapter.getCount(); - return itemCount > 0 - && (getFirstVisiblePosition() > 0 || getLastVisiblePosition() < itemCount - 1); - } - return false; - } - - @Override - protected boolean canAnimate() { - return super.canAnimate() && mItemCount > 0; - } - - void handleDataChanged() { - final int count = mItemCount; - boolean found = false; - - if (count > 0) { - - int newPos; - - // Find the row we are supposed to sync to - if (mNeedSync) { - // Update this first, since setNextSelectedPositionInt inspects - // it - mNeedSync = false; - - // See if we can find a position in the new data with the same - // id as the old selection - newPos = findSyncPosition(); - if (newPos >= 0) { - // Verify that new selection is selectable - int selectablePos = lookForSelectablePosition(newPos, true); - if (selectablePos == newPos) { - // Same row id is selected - setNextSelectedPositionInt(newPos); - found = true; - } - } - } - if (!found) { - // Try to use the same position if we can't find matching data - newPos = getSelectedItemPosition(); - - // Pin position to the available range - if (newPos >= count) { - newPos = count - 1; - } - if (newPos < 0) { - newPos = 0; - } - - // Make sure we select something selectable -- first look down - int selectablePos = lookForSelectablePosition(newPos, true); - if (selectablePos < 0) { - // Looking down didn't work -- try looking up - selectablePos = lookForSelectablePosition(newPos, false); - } - if (selectablePos >= 0) { - setNextSelectedPositionInt(selectablePos); - checkSelectionChanged(); - found = true; - } - } - } - if (!found) { - // Nothing is selected - mSelectedPosition = INVALID_POSITION; - mSelectedRowId = INVALID_ROW_ID; - mNextSelectedPosition = INVALID_POSITION; - mNextSelectedRowId = INVALID_ROW_ID; - mNeedSync = false; - checkSelectionChanged(); - } - } - - void checkSelectionChanged() { - if ((mSelectedPosition != mOldSelectedPosition) || (mSelectedRowId != mOldSelectedRowId)) { - selectionChanged(); - mOldSelectedPosition = mSelectedPosition; - mOldSelectedRowId = mSelectedRowId; - } - } - - /** - * Searches the adapter for a position matching mSyncRowId. The search starts at mSyncPosition - * and then alternates between moving up and moving down until 1) we find the right position, or - * 2) we run out of time, or 3) we have looked at every position - * - * @return Position of the row that matches mSyncRowId, or {@link #INVALID_POSITION} if it can't - * be found - */ - int findSyncPosition() { - int count = mItemCount; - - if (count == 0) { - return INVALID_POSITION; - } - - long idToMatch = mSyncRowId; - int seed = mSyncPosition; - - // If there isn't a selection don't hunt for it - if (idToMatch == INVALID_ROW_ID) { - return INVALID_POSITION; - } - - // Pin seed to reasonable values - seed = Math.max(0, seed); - seed = Math.min(count - 1, seed); - - long endTime = SystemClock.uptimeMillis() + SYNC_MAX_DURATION_MILLIS; - - long rowId; - - // first position scanned so far - int first = seed; - - // last position scanned so far - int last = seed; - - // True if we should move down on the next iteration - boolean next = false; - - // True when we have looked at the first item in the data - boolean hitFirst; - - // True when we have looked at the last item in the data - boolean hitLast; - - // Get the item ID locally (instead of getItemIdAtPosition), so - // we need the adapter - T adapter = getAdapter(); - if (adapter == null) { - return INVALID_POSITION; - } - - while (SystemClock.uptimeMillis() <= endTime) { - rowId = adapter.getItemId(seed); - if (rowId == idToMatch) { - // Found it! - return seed; - } - - hitLast = last == count - 1; - hitFirst = first == 0; - - if (hitLast && hitFirst) { - // Looked at everything - break; - } - - if (hitFirst || (next && !hitLast)) { - // Either we hit the top, or we are trying to move down - last++; - seed = last; - // Try going up next time - next = false; - } else if (hitLast || (!next && !hitFirst)) { - // Either we hit the bottom, or we are trying to move up - first--; - seed = first; - // Try going down next time - next = true; - } - - } - - return INVALID_POSITION; - } - - /** - * Find a position that can be selected (i.e., is not a separator). - * - * @param position The starting position to look at. - * @param lookDown Whether to look down for other positions. - * @return The next selectable position starting at position and then searching either up or - * down. Returns {@link #INVALID_POSITION} if nothing can be found. - */ - int lookForSelectablePosition(int position, boolean lookDown) { - return position; - } - - /** - * Utility to keep mSelectedPosition and mSelectedRowId in sync - * @param position Our current position - */ - void setSelectedPositionInt(int position) { - mSelectedPosition = position; - mSelectedRowId = getItemIdAtPosition(position); - } - - /** - * Utility to keep mNextSelectedPosition and mNextSelectedRowId in sync - * @param position Intended value for mSelectedPosition the next time we go - * through layout - */ - void setNextSelectedPositionInt(int position) { - mNextSelectedPosition = position; - mNextSelectedRowId = getItemIdAtPosition(position); - // If we are trying to sync to the selection, update that too - if (mNeedSync && mSyncMode == SYNC_SELECTED_POSITION && position >= 0) { - mSyncPosition = position; - mSyncRowId = mNextSelectedRowId; - } - } - - /** - * Remember enough information to restore the screen state when the data has - * changed. - * - */ - void rememberSyncState() { - if (getChildCount() > 0) { - mNeedSync = true; - mSyncHeight = mLayoutHeight; - if (mSelectedPosition >= 0) { - // Sync the selection state - View v = getChildAt(mSelectedPosition - mFirstPosition); - mSyncRowId = mNextSelectedRowId; - mSyncPosition = mNextSelectedPosition; - if (v != null) { - mSpecificTop = v.getTop(); - } - mSyncMode = SYNC_SELECTED_POSITION; - } else { - // Sync the based on the offset of the first view - View v = getChildAt(0); - T adapter = getAdapter(); - if (mFirstPosition >= 0 && mFirstPosition < adapter.getCount()) { - mSyncRowId = adapter.getItemId(mFirstPosition); - } else { - mSyncRowId = NO_ID; - } - mSyncPosition = mFirstPosition; - if (v != null) { - mSpecificTop = v.getTop(); - } - mSyncMode = SYNC_FIRST_POSITION; - } - } - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/IcsLinearLayout.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/IcsLinearLayout.java deleted file mode 100644 index 1b4463a59..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/IcsLinearLayout.java +++ /dev/null @@ -1,272 +0,0 @@ -package com.actionbarsherlock.internal.widget; - -import android.content.Context; -import android.content.res.TypedArray; -import android.graphics.Canvas; -import android.graphics.drawable.Drawable; -import android.util.AttributeSet; -import android.view.View; -import com.actionbarsherlock.internal.nineoldandroids.widget.NineLinearLayout; - -/** - * A simple extension of a regular linear layout that supports the divider API - * of Android 4.0+. The dividers are added adjacent to the children by changing - * their layout params. If you need to rely on the margins which fall in the - * same orientation as the layout you should wrap the child in a simple - * {@link android.widget.FrameLayout} so it can receive the margin. - */ -public class IcsLinearLayout extends NineLinearLayout { - private static final int[] LinearLayout = new int[] { - /* 0 */ android.R.attr.divider, - /* 1 */ android.R.attr.showDividers, - /* 2 */ android.R.attr.dividerPadding, - }; - private static final int LinearLayout_divider = 0; - private static final int LinearLayout_showDividers = 1; - private static final int LinearLayout_dividerPadding = 2; - - /** - * Don't show any dividers. - */ - public static final int SHOW_DIVIDER_NONE = 0; - /** - * Show a divider at the beginning of the group. - */ - public static final int SHOW_DIVIDER_BEGINNING = 1; - /** - * Show dividers between each item in the group. - */ - public static final int SHOW_DIVIDER_MIDDLE = 2; - /** - * Show a divider at the end of the group. - */ - public static final int SHOW_DIVIDER_END = 4; - - - private Drawable mDivider; - private int mDividerWidth; - private int mDividerHeight; - private int mShowDividers; - private int mDividerPadding; - - - public IcsLinearLayout(Context context, AttributeSet attrs) { - super(context, attrs); - - TypedArray a = context.obtainStyledAttributes(attrs, /*com.android.internal.R.styleable.*/LinearLayout); - - setDividerDrawable(a.getDrawable(/*com.android.internal.R.styleable.*/LinearLayout_divider)); - mShowDividers = a.getInt(/*com.android.internal.R.styleable.*/LinearLayout_showDividers, SHOW_DIVIDER_NONE); - mDividerPadding = a.getDimensionPixelSize(/*com.android.internal.R.styleable.*/LinearLayout_dividerPadding, 0); - - a.recycle(); - } - - /** - * Set how dividers should be shown between items in this layout - * - * @param showDividers One or more of {@link #SHOW_DIVIDER_BEGINNING}, - * {@link #SHOW_DIVIDER_MIDDLE}, or {@link #SHOW_DIVIDER_END}, - * or {@link #SHOW_DIVIDER_NONE} to show no dividers. - */ - public void setShowDividers(int showDividers) { - if (showDividers != mShowDividers) { - requestLayout(); - invalidate(); //XXX This is required if you are toggling a divider off - } - mShowDividers = showDividers; - } - - /** - * @return A flag set indicating how dividers should be shown around items. - * @see #setShowDividers(int) - */ - public int getShowDividers() { - return mShowDividers; - } - - /** - * Set a drawable to be used as a divider between items. - * @param divider Drawable that will divide each item. - * @see #setShowDividers(int) - */ - public void setDividerDrawable(Drawable divider) { - if (divider == mDivider) { - return; - } - mDivider = divider; - if (divider != null) { - mDividerWidth = divider.getIntrinsicWidth(); - mDividerHeight = divider.getIntrinsicHeight(); - } else { - mDividerWidth = 0; - mDividerHeight = 0; - } - setWillNotDraw(divider == null); - requestLayout(); - } - - /** - * Set padding displayed on both ends of dividers. - * - * @param padding Padding value in pixels that will be applied to each end - * - * @see #setShowDividers(int) - * @see #setDividerDrawable(Drawable) - * @see #getDividerPadding() - */ - public void setDividerPadding(int padding) { - mDividerPadding = padding; - } - - /** - * Get the padding size used to inset dividers in pixels - * - * @see #setShowDividers(int) - * @see #setDividerDrawable(Drawable) - * @see #setDividerPadding(int) - */ - public int getDividerPadding() { - return mDividerPadding; - } - - /** - * Get the width of the current divider drawable. - * - * @hide Used internally by framework. - */ - public int getDividerWidth() { - return mDividerWidth; - } - - @Override - protected void measureChildWithMargins(View child, int parentWidthMeasureSpec, int widthUsed, int parentHeightMeasureSpec, int heightUsed) { - final int index = indexOfChild(child); - final int orientation = getOrientation(); - final LayoutParams params = (LayoutParams) child.getLayoutParams(); - if (hasDividerBeforeChildAt(index)) { - if (orientation == VERTICAL) { - //Account for the divider by pushing everything up - params.topMargin = mDividerHeight; - } else { - //Account for the divider by pushing everything left - params.leftMargin = mDividerWidth; - } - } - - final int count = getChildCount(); - if (index == count - 1) { - if (hasDividerBeforeChildAt(count)) { - if (orientation == VERTICAL) { - params.bottomMargin = mDividerHeight; - } else { - params.rightMargin = mDividerWidth; - } - } - } - super.measureChildWithMargins(child, parentWidthMeasureSpec, widthUsed, parentHeightMeasureSpec, heightUsed); - } - - @Override - protected void onDraw(Canvas canvas) { - if (mDivider != null) { - if (getOrientation() == VERTICAL) { - drawDividersVertical(canvas); - } else { - drawDividersHorizontal(canvas); - } - } - super.onDraw(canvas); - } - - void drawDividersVertical(Canvas canvas) { - final int count = getChildCount(); - for (int i = 0; i < count; i++) { - final View child = getChildAt(i); - - if (child != null && child.getVisibility() != GONE) { - if (hasDividerBeforeChildAt(i)) { - final LayoutParams lp = (LayoutParams) child.getLayoutParams(); - final int top = child.getTop() - lp.topMargin/* - mDividerHeight*/; - drawHorizontalDivider(canvas, top); - } - } - } - - if (hasDividerBeforeChildAt(count)) { - final View child = getChildAt(count - 1); - int bottom = 0; - if (child == null) { - bottom = getHeight() - getPaddingBottom() - mDividerHeight; - } else { - final LayoutParams lp = (LayoutParams) child.getLayoutParams(); - bottom = child.getBottom()/* + lp.bottomMargin*/; - } - drawHorizontalDivider(canvas, bottom); - } - } - - void drawDividersHorizontal(Canvas canvas) { - final int count = getChildCount(); - for (int i = 0; i < count; i++) { - final View child = getChildAt(i); - - if (child != null && child.getVisibility() != GONE) { - if (hasDividerBeforeChildAt(i)) { - final LayoutParams lp = (LayoutParams) child.getLayoutParams(); - final int left = child.getLeft() - lp.leftMargin/* - mDividerWidth*/; - drawVerticalDivider(canvas, left); - } - } - } - - if (hasDividerBeforeChildAt(count)) { - final View child = getChildAt(count - 1); - int right = 0; - if (child == null) { - right = getWidth() - getPaddingRight() - mDividerWidth; - } else { - final LayoutParams lp = (LayoutParams) child.getLayoutParams(); - right = child.getRight()/* + lp.rightMargin*/; - } - drawVerticalDivider(canvas, right); - } - } - - void drawHorizontalDivider(Canvas canvas, int top) { - mDivider.setBounds(getPaddingLeft() + mDividerPadding, top, - getWidth() - getPaddingRight() - mDividerPadding, top + mDividerHeight); - mDivider.draw(canvas); - } - - void drawVerticalDivider(Canvas canvas, int left) { - mDivider.setBounds(left, getPaddingTop() + mDividerPadding, - left + mDividerWidth, getHeight() - getPaddingBottom() - mDividerPadding); - mDivider.draw(canvas); - } - - /** - * Determines where to position dividers between children. - * - * @param childIndex Index of child to check for preceding divider - * @return true if there should be a divider before the child at childIndex - * @hide Pending API consideration. Currently only used internally by the system. - */ - protected boolean hasDividerBeforeChildAt(int childIndex) { - if (childIndex == 0) { - return (mShowDividers & SHOW_DIVIDER_BEGINNING) != 0; - } else if (childIndex == getChildCount()) { - return (mShowDividers & SHOW_DIVIDER_END) != 0; - } else if ((mShowDividers & SHOW_DIVIDER_MIDDLE) != 0) { - boolean hasVisibleViewBefore = false; - for (int i = childIndex - 1; i >= 0; i--) { - if (getChildAt(i).getVisibility() != GONE) { - hasVisibleViewBefore = true; - break; - } - } - return hasVisibleViewBefore; - } - return false; - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/IcsListPopupWindow.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/IcsListPopupWindow.java deleted file mode 100644 index d13c6cea9..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/IcsListPopupWindow.java +++ /dev/null @@ -1,644 +0,0 @@ -package com.actionbarsherlock.internal.widget; - -import com.actionbarsherlock.R; - -import android.content.Context; -import android.content.res.Resources; -import android.database.DataSetObserver; -import android.graphics.Rect; -import android.graphics.drawable.Drawable; -import android.os.Build; -import android.os.Handler; -import android.util.AttributeSet; -import android.view.ContextThemeWrapper; -import android.view.MotionEvent; -import android.view.View; -import android.view.View.MeasureSpec; -import android.view.View.OnTouchListener; -import android.view.ViewGroup; -import android.view.ViewParent; -import android.widget.AbsListView; -import android.widget.AdapterView; -import android.widget.LinearLayout; -import android.widget.ListAdapter; -import android.widget.ListView; -import android.widget.PopupWindow; - -/** - * A proxy between pre- and post-Honeycomb implementations of this class. - */ -public class IcsListPopupWindow { - /** - * This value controls the length of time that the user - * must leave a pointer down without scrolling to expand - * the autocomplete dropdown list to cover the IME. - */ - private static final int EXPAND_LIST_TIMEOUT = 250; - - private Context mContext; - private PopupWindow mPopup; - private ListAdapter mAdapter; - private DropDownListView mDropDownList; - - private int mDropDownHeight = ViewGroup.LayoutParams.WRAP_CONTENT; - private int mDropDownWidth = ViewGroup.LayoutParams.WRAP_CONTENT; - private int mDropDownHorizontalOffset; - private int mDropDownVerticalOffset; - private boolean mDropDownVerticalOffsetSet; - - private int mListItemExpandMaximum = Integer.MAX_VALUE; - - private View mPromptView; - private int mPromptPosition = POSITION_PROMPT_ABOVE; - - private DataSetObserver mObserver; - - private View mDropDownAnchorView; - - private Drawable mDropDownListHighlight; - - private AdapterView.OnItemClickListener mItemClickListener; - private AdapterView.OnItemSelectedListener mItemSelectedListener; - - private final ResizePopupRunnable mResizePopupRunnable = new ResizePopupRunnable(); - private final PopupTouchInterceptor mTouchInterceptor = new PopupTouchInterceptor(); - private final PopupScrollListener mScrollListener = new PopupScrollListener(); - private final ListSelectorHider mHideSelector = new ListSelectorHider(); - - private Handler mHandler = new Handler(); - - private Rect mTempRect = new Rect(); - - private boolean mModal; - - public static final int POSITION_PROMPT_ABOVE = 0; - public static final int POSITION_PROMPT_BELOW = 1; - - public IcsListPopupWindow(Context context) { - this(context, null, R.attr.listPopupWindowStyle); - } - - public IcsListPopupWindow(Context context, AttributeSet attrs, int defStyleAttr) { - mContext = context; - mPopup = new PopupWindow(context, attrs, defStyleAttr); - mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED); - } - - public IcsListPopupWindow(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { - mContext = context; - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { - Context wrapped = new ContextThemeWrapper(context, defStyleRes); - mPopup = new PopupWindow(wrapped, attrs, defStyleAttr); - } else { - mPopup = new PopupWindow(context, attrs, defStyleAttr, defStyleRes); - } - mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED); - } - - public void setAdapter(ListAdapter adapter) { - if (mObserver == null) { - mObserver = new PopupDataSetObserver(); - } else if (mAdapter != null) { - mAdapter.unregisterDataSetObserver(mObserver); - } - mAdapter = adapter; - if (mAdapter != null) { - adapter.registerDataSetObserver(mObserver); - } - - if (mDropDownList != null) { - mDropDownList.setAdapter(mAdapter); - } - } - - public void setPromptPosition(int position) { - mPromptPosition = position; - } - - public void setModal(boolean modal) { - mModal = true; - mPopup.setFocusable(modal); - } - - public void setBackgroundDrawable(Drawable d) { - mPopup.setBackgroundDrawable(d); - } - - public void setAnchorView(View anchor) { - mDropDownAnchorView = anchor; - } - - public void setHorizontalOffset(int offset) { - mDropDownHorizontalOffset = offset; - } - - public void setVerticalOffset(int offset) { - mDropDownVerticalOffset = offset; - mDropDownVerticalOffsetSet = true; - } - - public void setContentWidth(int width) { - Drawable popupBackground = mPopup.getBackground(); - if (popupBackground != null) { - popupBackground.getPadding(mTempRect); - mDropDownWidth = mTempRect.left + mTempRect.right + width; - } else { - mDropDownWidth = width; - } - } - - public void setOnItemClickListener(AdapterView.OnItemClickListener clickListener) { - mItemClickListener = clickListener; - } - - public void show() { - int height = buildDropDown(); - - int widthSpec = 0; - int heightSpec = 0; - - boolean noInputMethod = isInputMethodNotNeeded(); - //XXX mPopup.setAllowScrollingAnchorParent(!noInputMethod); - - if (mPopup.isShowing()) { - if (mDropDownWidth == ViewGroup.LayoutParams.MATCH_PARENT) { - // The call to PopupWindow's update method below can accept -1 for any - // value you do not want to update. - widthSpec = -1; - } else if (mDropDownWidth == ViewGroup.LayoutParams.WRAP_CONTENT) { - widthSpec = mDropDownAnchorView.getWidth(); - } else { - widthSpec = mDropDownWidth; - } - - if (mDropDownHeight == ViewGroup.LayoutParams.MATCH_PARENT) { - // The call to PopupWindow's update method below can accept -1 for any - // value you do not want to update. - heightSpec = noInputMethod ? height : ViewGroup.LayoutParams.MATCH_PARENT; - if (noInputMethod) { - mPopup.setWindowLayoutMode( - mDropDownWidth == ViewGroup.LayoutParams.MATCH_PARENT ? - ViewGroup.LayoutParams.MATCH_PARENT : 0, 0); - } else { - mPopup.setWindowLayoutMode( - mDropDownWidth == ViewGroup.LayoutParams.MATCH_PARENT ? - ViewGroup.LayoutParams.MATCH_PARENT : 0, - ViewGroup.LayoutParams.MATCH_PARENT); - } - } else if (mDropDownHeight == ViewGroup.LayoutParams.WRAP_CONTENT) { - heightSpec = height; - } else { - heightSpec = mDropDownHeight; - } - - mPopup.setOutsideTouchable(true); - - mPopup.update(mDropDownAnchorView, mDropDownHorizontalOffset, - mDropDownVerticalOffset, widthSpec, heightSpec); - } else { - if (mDropDownWidth == ViewGroup.LayoutParams.MATCH_PARENT) { - widthSpec = ViewGroup.LayoutParams.MATCH_PARENT; - } else { - if (mDropDownWidth == ViewGroup.LayoutParams.WRAP_CONTENT) { - mPopup.setWidth(mDropDownAnchorView.getWidth()); - } else { - mPopup.setWidth(mDropDownWidth); - } - } - - if (mDropDownHeight == ViewGroup.LayoutParams.MATCH_PARENT) { - heightSpec = ViewGroup.LayoutParams.MATCH_PARENT; - } else { - if (mDropDownHeight == ViewGroup.LayoutParams.WRAP_CONTENT) { - mPopup.setHeight(height); - } else { - mPopup.setHeight(mDropDownHeight); - } - } - - mPopup.setWindowLayoutMode(widthSpec, heightSpec); - //XXX mPopup.setClipToScreenEnabled(true); - - // use outside touchable to dismiss drop down when touching outside of it, so - // only set this if the dropdown is not always visible - mPopup.setOutsideTouchable(true); - mPopup.setTouchInterceptor(mTouchInterceptor); - mPopup.showAsDropDown(mDropDownAnchorView, - mDropDownHorizontalOffset, mDropDownVerticalOffset); - mDropDownList.setSelection(ListView.INVALID_POSITION); - - if (!mModal || mDropDownList.isInTouchMode()) { - clearListSelection(); - } - if (!mModal) { - mHandler.post(mHideSelector); - } - } - } - - public void dismiss() { - mPopup.dismiss(); - if (mPromptView != null) { - final ViewParent parent = mPromptView.getParent(); - if (parent instanceof ViewGroup) { - final ViewGroup group = (ViewGroup) parent; - group.removeView(mPromptView); - } - } - mPopup.setContentView(null); - mDropDownList = null; - mHandler.removeCallbacks(mResizePopupRunnable); - } - - public void setOnDismissListener(PopupWindow.OnDismissListener listener) { - mPopup.setOnDismissListener(listener); - } - - public void setInputMethodMode(int mode) { - mPopup.setInputMethodMode(mode); - } - - public void clearListSelection() { - final DropDownListView list = mDropDownList; - if (list != null) { - // WARNING: Please read the comment where mListSelectionHidden is declared - list.mListSelectionHidden = true; - //XXX list.hideSelector(); - list.requestLayout(); - } - } - - public boolean isShowing() { - return mPopup.isShowing(); - } - - private boolean isInputMethodNotNeeded() { - return mPopup.getInputMethodMode() == PopupWindow.INPUT_METHOD_NOT_NEEDED; - } - - public ListView getListView() { - return mDropDownList; - } - - private int buildDropDown() { - ViewGroup dropDownView; - int otherHeights = 0; - - if (mDropDownList == null) { - Context context = mContext; - - mDropDownList = new DropDownListView(context, !mModal); - if (mDropDownListHighlight != null) { - mDropDownList.setSelector(mDropDownListHighlight); - } - mDropDownList.setAdapter(mAdapter); - mDropDownList.setOnItemClickListener(mItemClickListener); - mDropDownList.setFocusable(true); - mDropDownList.setFocusableInTouchMode(true); - mDropDownList.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { - public void onItemSelected(AdapterView parent, View view, - int position, long id) { - - if (position != -1) { - DropDownListView dropDownList = mDropDownList; - - if (dropDownList != null) { - dropDownList.mListSelectionHidden = false; - } - } - } - - public void onNothingSelected(AdapterView parent) { - } - }); - mDropDownList.setOnScrollListener(mScrollListener); - - if (mItemSelectedListener != null) { - mDropDownList.setOnItemSelectedListener(mItemSelectedListener); - } - - dropDownView = mDropDownList; - - View hintView = mPromptView; - if (hintView != null) { - // if an hint has been specified, we accomodate more space for it and - // add a text view in the drop down menu, at the bottom of the list - LinearLayout hintContainer = new LinearLayout(context); - hintContainer.setOrientation(LinearLayout.VERTICAL); - - LinearLayout.LayoutParams hintParams = new LinearLayout.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, 0, 1.0f - ); - - switch (mPromptPosition) { - case POSITION_PROMPT_BELOW: - hintContainer.addView(dropDownView, hintParams); - hintContainer.addView(hintView); - break; - - case POSITION_PROMPT_ABOVE: - hintContainer.addView(hintView); - hintContainer.addView(dropDownView, hintParams); - break; - - default: - break; - } - - // measure the hint's height to find how much more vertical space - // we need to add to the drop down's height - int widthSpec = MeasureSpec.makeMeasureSpec(mDropDownWidth, MeasureSpec.AT_MOST); - int heightSpec = MeasureSpec.UNSPECIFIED; - hintView.measure(widthSpec, heightSpec); - - hintParams = (LinearLayout.LayoutParams) hintView.getLayoutParams(); - otherHeights = hintView.getMeasuredHeight() + hintParams.topMargin - + hintParams.bottomMargin; - - dropDownView = hintContainer; - } - - mPopup.setContentView(dropDownView); - } else { - dropDownView = (ViewGroup) mPopup.getContentView(); - final View view = mPromptView; - if (view != null) { - LinearLayout.LayoutParams hintParams = - (LinearLayout.LayoutParams) view.getLayoutParams(); - otherHeights = view.getMeasuredHeight() + hintParams.topMargin - + hintParams.bottomMargin; - } - } - - // getMaxAvailableHeight() subtracts the padding, so we put it back - // to get the available height for the whole window - int padding = 0; - Drawable background = mPopup.getBackground(); - if (background != null) { - background.getPadding(mTempRect); - padding = mTempRect.top + mTempRect.bottom; - - // If we don't have an explicit vertical offset, determine one from the window - // background so that content will line up. - if (!mDropDownVerticalOffsetSet) { - mDropDownVerticalOffset = -mTempRect.top; - } - } - - // Max height available on the screen for a popup. - boolean ignoreBottomDecorations = - mPopup.getInputMethodMode() == PopupWindow.INPUT_METHOD_NOT_NEEDED; - final int maxHeight = /*mPopup.*/getMaxAvailableHeight( - mDropDownAnchorView, mDropDownVerticalOffset, ignoreBottomDecorations); - - if (mDropDownHeight == ViewGroup.LayoutParams.MATCH_PARENT) { - return maxHeight + padding; - } - - final int listContent = /*mDropDownList.*/measureHeightOfChildren(MeasureSpec.UNSPECIFIED, - 0, -1/*ListView.NO_POSITION*/, maxHeight - otherHeights, -1); - // add padding only if the list has items in it, that way we don't show - // the popup if it is not needed - if (listContent > 0) otherHeights += padding; - - return listContent + otherHeights; - } - - private int getMaxAvailableHeight(View anchor, int yOffset, boolean ignoreBottomDecorations) { - final Rect displayFrame = new Rect(); - anchor.getWindowVisibleDisplayFrame(displayFrame); - - final int[] anchorPos = new int[2]; - anchor.getLocationOnScreen(anchorPos); - - int bottomEdge = displayFrame.bottom; - if (ignoreBottomDecorations) { - Resources res = anchor.getContext().getResources(); - bottomEdge = res.getDisplayMetrics().heightPixels; - } - final int distanceToBottom = bottomEdge - (anchorPos[1] + anchor.getHeight()) - yOffset; - final int distanceToTop = anchorPos[1] - displayFrame.top + yOffset; - - // anchorPos[1] is distance from anchor to top of screen - int returnedHeight = Math.max(distanceToBottom, distanceToTop); - if (mPopup.getBackground() != null) { - mPopup.getBackground().getPadding(mTempRect); - returnedHeight -= mTempRect.top + mTempRect.bottom; - } - - return returnedHeight; - } - - private int measureHeightOfChildren(int widthMeasureSpec, int startPosition, int endPosition, - final int maxHeight, int disallowPartialChildPosition) { - - final ListAdapter adapter = mAdapter; - if (adapter == null) { - return mDropDownList.getListPaddingTop() + mDropDownList.getListPaddingBottom(); - } - - // Include the padding of the list - int returnedHeight = mDropDownList.getListPaddingTop() + mDropDownList.getListPaddingBottom(); - final int dividerHeight = ((mDropDownList.getDividerHeight() > 0) && mDropDownList.getDivider() != null) ? mDropDownList.getDividerHeight() : 0; - // The previous height value that was less than maxHeight and contained - // no partial children - int prevHeightWithoutPartialChild = 0; - int i; - View child; - - // mItemCount - 1 since endPosition parameter is inclusive - endPosition = (endPosition == -1/*NO_POSITION*/) ? adapter.getCount() - 1 : endPosition; - - for (i = startPosition; i <= endPosition; ++i) { - child = mAdapter.getView(i, null, mDropDownList); - if (mDropDownList.getCacheColorHint() != 0) { - child.setDrawingCacheBackgroundColor(mDropDownList.getCacheColorHint()); - } - - measureScrapChild(child, i, widthMeasureSpec); - - if (i > 0) { - // Count the divider for all but one child - returnedHeight += dividerHeight; - } - - returnedHeight += child.getMeasuredHeight(); - - if (returnedHeight >= maxHeight) { - // We went over, figure out which height to return. If returnedHeight > maxHeight, - // then the i'th position did not fit completely. - return (disallowPartialChildPosition >= 0) // Disallowing is enabled (> -1) - && (i > disallowPartialChildPosition) // We've past the min pos - && (prevHeightWithoutPartialChild > 0) // We have a prev height - && (returnedHeight != maxHeight) // i'th child did not fit completely - ? prevHeightWithoutPartialChild - : maxHeight; - } - - if ((disallowPartialChildPosition >= 0) && (i >= disallowPartialChildPosition)) { - prevHeightWithoutPartialChild = returnedHeight; - } - } - - // At this point, we went through the range of children, and they each - // completely fit, so return the returnedHeight - return returnedHeight; - } - private void measureScrapChild(View child, int position, int widthMeasureSpec) { - ListView.LayoutParams p = (ListView.LayoutParams) child.getLayoutParams(); - if (p == null) { - p = new ListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.WRAP_CONTENT, 0); - child.setLayoutParams(p); - } - //XXX p.viewType = mAdapter.getItemViewType(position); - //XXX p.forceAdd = true; - - int childWidthSpec = ViewGroup.getChildMeasureSpec(widthMeasureSpec, - mDropDownList.getPaddingLeft() + mDropDownList.getPaddingRight(), p.width); - int lpHeight = p.height; - int childHeightSpec; - if (lpHeight > 0) { - childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY); - } else { - childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); - } - child.measure(childWidthSpec, childHeightSpec); - } - - private static class DropDownListView extends ListView { - /* - * WARNING: This is a workaround for a touch mode issue. - * - * Touch mode is propagated lazily to windows. This causes problems in - * the following scenario: - * - Type something in the AutoCompleteTextView and get some results - * - Move down with the d-pad to select an item in the list - * - Move up with the d-pad until the selection disappears - * - Type more text in the AutoCompleteTextView *using the soft keyboard* - * and get new results; you are now in touch mode - * - The selection comes back on the first item in the list, even though - * the list is supposed to be in touch mode - * - * Using the soft keyboard triggers the touch mode change but that change - * is propagated to our window only after the first list layout, therefore - * after the list attempts to resurrect the selection. - * - * The trick to work around this issue is to pretend the list is in touch - * mode when we know that the selection should not appear, that is when - * we know the user moved the selection away from the list. - * - * This boolean is set to true whenever we explicitly hide the list's - * selection and reset to false whenever we know the user moved the - * selection back to the list. - * - * When this boolean is true, isInTouchMode() returns true, otherwise it - * returns super.isInTouchMode(). - */ - private boolean mListSelectionHidden; - - private boolean mHijackFocus; - - public DropDownListView(Context context, boolean hijackFocus) { - super(context, null, /*com.android.internal.*/R.attr.dropDownListViewStyle); - mHijackFocus = hijackFocus; - // TODO: Add an API to control this - setCacheColorHint(0); // Transparent, since the background drawable could be anything. - } - - //XXX @Override - //View obtainView(int position, boolean[] isScrap) { - // View view = super.obtainView(position, isScrap); - - // if (view instanceof TextView) { - // ((TextView) view).setHorizontallyScrolling(true); - // } - - // return view; - //} - - @Override - public boolean isInTouchMode() { - // WARNING: Please read the comment where mListSelectionHidden is declared - return (mHijackFocus && mListSelectionHidden) || super.isInTouchMode(); - } - - @Override - public boolean hasWindowFocus() { - return mHijackFocus || super.hasWindowFocus(); - } - - @Override - public boolean isFocused() { - return mHijackFocus || super.isFocused(); - } - - @Override - public boolean hasFocus() { - return mHijackFocus || super.hasFocus(); - } - } - - private class PopupDataSetObserver extends DataSetObserver { - @Override - public void onChanged() { - if (isShowing()) { - // Resize the popup to fit new content - show(); - } - } - - @Override - public void onInvalidated() { - dismiss(); - } - } - - private class ListSelectorHider implements Runnable { - public void run() { - clearListSelection(); - } - } - - private class ResizePopupRunnable implements Runnable { - public void run() { - if (mDropDownList != null && mDropDownList.getCount() > mDropDownList.getChildCount() && - mDropDownList.getChildCount() <= mListItemExpandMaximum) { - mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED); - show(); - } - } - } - - private class PopupTouchInterceptor implements OnTouchListener { - public boolean onTouch(View v, MotionEvent event) { - final int action = event.getAction(); - final int x = (int) event.getX(); - final int y = (int) event.getY(); - - if (action == MotionEvent.ACTION_DOWN && - mPopup != null && mPopup.isShowing() && - (x >= 0 && x < mPopup.getWidth() && y >= 0 && y < mPopup.getHeight())) { - mHandler.postDelayed(mResizePopupRunnable, EXPAND_LIST_TIMEOUT); - } else if (action == MotionEvent.ACTION_UP) { - mHandler.removeCallbacks(mResizePopupRunnable); - } - return false; - } - } - - private class PopupScrollListener implements ListView.OnScrollListener { - public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, - int totalItemCount) { - - } - - public void onScrollStateChanged(AbsListView view, int scrollState) { - if (scrollState == SCROLL_STATE_TOUCH_SCROLL && - !isInputMethodNotNeeded() && mPopup.getContentView() != null) { - mHandler.removeCallbacks(mResizePopupRunnable); - mResizePopupRunnable.run(); - } - } - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/IcsProgressBar.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/IcsProgressBar.java deleted file mode 100644 index 1c02d4aca..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/IcsProgressBar.java +++ /dev/null @@ -1,1193 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.widget; - -import android.content.Context; -import android.content.res.TypedArray; -import android.graphics.Bitmap; -import android.graphics.BitmapShader; -import android.graphics.Canvas; -import android.graphics.Rect; -import android.graphics.Shader; -import android.graphics.drawable.Animatable; -import android.graphics.drawable.AnimationDrawable; -import android.graphics.drawable.BitmapDrawable; -import android.graphics.drawable.ClipDrawable; -import android.graphics.drawable.Drawable; -import android.graphics.drawable.LayerDrawable; -import android.graphics.drawable.ShapeDrawable; -import android.graphics.drawable.shapes.RoundRectShape; -import android.graphics.drawable.shapes.Shape; -import android.os.Build; -import android.os.Parcel; -import android.os.Parcelable; -import android.os.SystemClock; -import android.util.AttributeSet; -import android.view.Gravity; -import android.view.View; -import android.view.ViewDebug; -import android.view.accessibility.AccessibilityEvent; -import android.view.accessibility.AccessibilityManager; -import android.view.animation.AlphaAnimation; -import android.view.animation.Animation; -import android.view.animation.AnimationUtils; -import android.view.animation.Interpolator; -import android.view.animation.LinearInterpolator; -import android.view.animation.Transformation; -import android.widget.RemoteViews.RemoteView; - - -/** - *

- * Visual indicator of progress in some operation. Displays a bar to the user - * representing how far the operation has progressed; the application can - * change the amount of progress (modifying the length of the bar) as it moves - * forward. There is also a secondary progress displayable on a progress bar - * which is useful for displaying intermediate progress, such as the buffer - * level during a streaming playback progress bar. - *

- * - *

- * A progress bar can also be made indeterminate. In indeterminate mode, the - * progress bar shows a cyclic animation without an indication of progress. This mode is used by - * applications when the length of the task is unknown. The indeterminate progress bar can be either - * a spinning wheel or a horizontal bar. - *

- * - *

The following code example shows how a progress bar can be used from - * a worker thread to update the user interface to notify the user of progress: - *

- * - *
- * public class MyActivity extends Activity {
- *     private static final int PROGRESS = 0x1;
- *
- *     private ProgressBar mProgress;
- *     private int mProgressStatus = 0;
- *
- *     private Handler mHandler = new Handler();
- *
- *     protected void onCreate(Bundle icicle) {
- *         super.onCreate(icicle);
- *
- *         setContentView(R.layout.progressbar_activity);
- *
- *         mProgress = (ProgressBar) findViewById(R.id.progress_bar);
- *
- *         // Start lengthy operation in a background thread
- *         new Thread(new Runnable() {
- *             public void run() {
- *                 while (mProgressStatus < 100) {
- *                     mProgressStatus = doWork();
- *
- *                     // Update the progress bar
- *                     mHandler.post(new Runnable() {
- *                         public void run() {
- *                             mProgress.setProgress(mProgressStatus);
- *                         }
- *                     });
- *                 }
- *             }
- *         }).start();
- *     }
- * }
- * - *

To add a progress bar to a layout file, you can use the {@code <ProgressBar>} element. - * By default, the progress bar is a spinning wheel (an indeterminate indicator). To change to a - * horizontal progress bar, apply the {@link android.R.style#Widget_ProgressBar_Horizontal - * Widget.ProgressBar.Horizontal} style, like so:

- * - *
- * <ProgressBar
- *     style="@android:style/Widget.ProgressBar.Horizontal"
- *     ... />
- * - *

If you will use the progress bar to show real progress, you must use the horizontal bar. You - * can then increment the progress with {@link #incrementProgressBy incrementProgressBy()} or - * {@link #setProgress setProgress()}. By default, the progress bar is full when it reaches 100. If - * necessary, you can adjust the maximum value (the value for a full bar) using the {@link - * android.R.styleable#ProgressBar_max android:max} attribute. Other attributes available are listed - * below.

- * - *

Another common style to apply to the progress bar is {@link - * android.R.style#Widget_ProgressBar_Small Widget.ProgressBar.Small}, which shows a smaller - * version of the spinning wheel—useful when waiting for content to load. - * For example, you can insert this kind of progress bar into your default layout for - * a view that will be populated by some content fetched from the Internet—the spinning wheel - * appears immediately and when your application receives the content, it replaces the progress bar - * with the loaded content. For example:

- * - *
- * <LinearLayout
- *     android:orientation="horizontal"
- *     ... >
- *     <ProgressBar
- *         android:layout_width="wrap_content"
- *         android:layout_height="wrap_content"
- *         style="@android:style/Widget.ProgressBar.Small"
- *         android:layout_marginRight="5dp" />
- *     <TextView
- *         android:layout_width="wrap_content"
- *         android:layout_height="wrap_content"
- *         android:text="@string/loading" />
- * </LinearLayout>
- * - *

Other progress bar styles provided by the system include:

- *
    - *
  • {@link android.R.style#Widget_ProgressBar_Horizontal Widget.ProgressBar.Horizontal}
  • - *
  • {@link android.R.style#Widget_ProgressBar_Small Widget.ProgressBar.Small}
  • - *
  • {@link android.R.style#Widget_ProgressBar_Large Widget.ProgressBar.Large}
  • - *
  • {@link android.R.style#Widget_ProgressBar_Inverse Widget.ProgressBar.Inverse}
  • - *
  • {@link android.R.style#Widget_ProgressBar_Small_Inverse - * Widget.ProgressBar.Small.Inverse}
  • - *
  • {@link android.R.style#Widget_ProgressBar_Large_Inverse - * Widget.ProgressBar.Large.Inverse}
  • - *
- *

The "inverse" styles provide an inverse color scheme for the spinner, which may be necessary - * if your application uses a light colored theme (a white background).

- * - *

XML attributes - *

- * See {@link android.R.styleable#ProgressBar ProgressBar Attributes}, - * {@link android.R.styleable#View View Attributes} - *

- * - * @attr ref android.R.styleable#ProgressBar_animationResolution - * @attr ref android.R.styleable#ProgressBar_indeterminate - * @attr ref android.R.styleable#ProgressBar_indeterminateBehavior - * @attr ref android.R.styleable#ProgressBar_indeterminateDrawable - * @attr ref android.R.styleable#ProgressBar_indeterminateDuration - * @attr ref android.R.styleable#ProgressBar_indeterminateOnly - * @attr ref android.R.styleable#ProgressBar_interpolator - * @attr ref android.R.styleable#ProgressBar_max - * @attr ref android.R.styleable#ProgressBar_maxHeight - * @attr ref android.R.styleable#ProgressBar_maxWidth - * @attr ref android.R.styleable#ProgressBar_minHeight - * @attr ref android.R.styleable#ProgressBar_minWidth - * @attr ref android.R.styleable#ProgressBar_progress - * @attr ref android.R.styleable#ProgressBar_progressDrawable - * @attr ref android.R.styleable#ProgressBar_secondaryProgress - */ -@RemoteView -public class IcsProgressBar extends View { - private static final boolean IS_HONEYCOMB = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB; - private static final int MAX_LEVEL = 10000; - private static final int ANIMATION_RESOLUTION = 200; - private static final int TIMEOUT_SEND_ACCESSIBILITY_EVENT = 200; - - private static final int[] ProgressBar = new int[] { - android.R.attr.maxWidth, - android.R.attr.maxHeight, - android.R.attr.max, - android.R.attr.progress, - android.R.attr.secondaryProgress, - android.R.attr.indeterminate, - android.R.attr.indeterminateOnly, - android.R.attr.indeterminateDrawable, - android.R.attr.progressDrawable, - android.R.attr.indeterminateDuration, - android.R.attr.indeterminateBehavior, - android.R.attr.minWidth, - android.R.attr.minHeight, - android.R.attr.interpolator, - android.R.attr.animationResolution, - }; - private static final int ProgressBar_maxWidth = 0; - private static final int ProgressBar_maxHeight = 1; - private static final int ProgressBar_max = 2; - private static final int ProgressBar_progress = 3; - private static final int ProgressBar_secondaryProgress = 4; - private static final int ProgressBar_indeterminate = 5; - private static final int ProgressBar_indeterminateOnly = 6; - private static final int ProgressBar_indeterminateDrawable = 7; - private static final int ProgressBar_progressDrawable = 8; - private static final int ProgressBar_indeterminateDuration = 9; - private static final int ProgressBar_indeterminateBehavior = 10; - private static final int ProgressBar_minWidth = 11; - private static final int ProgressBar_minHeight = 12; - private static final int ProgressBar_interpolator = 13; - private static final int ProgressBar_animationResolution = 14; - - int mMinWidth; - int mMaxWidth; - int mMinHeight; - int mMaxHeight; - - private int mProgress; - private int mSecondaryProgress; - private int mMax; - - private int mBehavior; - private int mDuration; - private boolean mIndeterminate; - private boolean mOnlyIndeterminate; - private Transformation mTransformation; - private AlphaAnimation mAnimation; - private Drawable mIndeterminateDrawable; - private int mIndeterminateRealLeft; - private int mIndeterminateRealTop; - private Drawable mProgressDrawable; - private Drawable mCurrentDrawable; - Bitmap mSampleTile; - private boolean mNoInvalidate; - private Interpolator mInterpolator; - private RefreshProgressRunnable mRefreshProgressRunnable; - private long mUiThreadId; - private boolean mShouldStartAnimationDrawable; - private long mLastDrawTime; - - private boolean mInDrawing; - - private int mAnimationResolution; - - private AccessibilityManager mAccessibilityManager; - private AccessibilityEventSender mAccessibilityEventSender; - - /** - * Create a new progress bar with range 0...100 and initial progress of 0. - * @param context the application environment - */ - public IcsProgressBar(Context context) { - this(context, null); - } - - public IcsProgressBar(Context context, AttributeSet attrs) { - this(context, attrs, android.R.attr.progressBarStyle); - } - - public IcsProgressBar(Context context, AttributeSet attrs, int defStyle) { - this(context, attrs, defStyle, 0); - } - - /** - * @hide - */ - public IcsProgressBar(Context context, AttributeSet attrs, int defStyle, int styleRes) { - super(context, attrs, defStyle); - mUiThreadId = Thread.currentThread().getId(); - initProgressBar(); - - TypedArray a = - context.obtainStyledAttributes(attrs, /*R.styleable.*/ProgressBar, defStyle, styleRes); - - mNoInvalidate = true; - - Drawable drawable = a.getDrawable(/*R.styleable.*/ProgressBar_progressDrawable); - if (drawable != null) { - drawable = tileify(drawable, false); - // Calling this method can set mMaxHeight, make sure the corresponding - // XML attribute for mMaxHeight is read after calling this method - setProgressDrawable(drawable); - } - - - mDuration = a.getInt(/*R.styleable.*/ProgressBar_indeterminateDuration, mDuration); - - mMinWidth = a.getDimensionPixelSize(/*R.styleable.*/ProgressBar_minWidth, mMinWidth); - mMaxWidth = a.getDimensionPixelSize(/*R.styleable.*/ProgressBar_maxWidth, mMaxWidth); - mMinHeight = a.getDimensionPixelSize(/*R.styleable.*/ProgressBar_minHeight, mMinHeight); - mMaxHeight = a.getDimensionPixelSize(/*R.styleable.*/ProgressBar_maxHeight, mMaxHeight); - - mBehavior = a.getInt(/*R.styleable.*/ProgressBar_indeterminateBehavior, mBehavior); - - final int resID = a.getResourceId( - /*com.android.internal.R.styleable.*/ProgressBar_interpolator, - android.R.anim.linear_interpolator); // default to linear interpolator - if (resID > 0) { - setInterpolator(context, resID); - } - - setMax(a.getInt(/*R.styleable.*/ProgressBar_max, mMax)); - - setProgress(a.getInt(/*R.styleable.*/ProgressBar_progress, mProgress)); - - setSecondaryProgress( - a.getInt(/*R.styleable.*/ProgressBar_secondaryProgress, mSecondaryProgress)); - - drawable = a.getDrawable(/*R.styleable.*/ProgressBar_indeterminateDrawable); - if (drawable != null) { - drawable = tileifyIndeterminate(drawable); - setIndeterminateDrawable(drawable); - } - - mOnlyIndeterminate = a.getBoolean( - /*R.styleable.*/ProgressBar_indeterminateOnly, mOnlyIndeterminate); - - mNoInvalidate = false; - - setIndeterminate(mOnlyIndeterminate || a.getBoolean( - /*R.styleable.*/ProgressBar_indeterminate, mIndeterminate)); - - mAnimationResolution = a.getInteger(/*R.styleable.*/ProgressBar_animationResolution, - ANIMATION_RESOLUTION); - - a.recycle(); - - mAccessibilityManager = (AccessibilityManager)context.getSystemService(Context.ACCESSIBILITY_SERVICE); - } - - /** - * Converts a drawable to a tiled version of itself. It will recursively - * traverse layer and state list drawables. - */ - private Drawable tileify(Drawable drawable, boolean clip) { - - if (drawable instanceof LayerDrawable) { - LayerDrawable background = (LayerDrawable) drawable; - final int N = background.getNumberOfLayers(); - Drawable[] outDrawables = new Drawable[N]; - - for (int i = 0; i < N; i++) { - int id = background.getId(i); - outDrawables[i] = tileify(background.getDrawable(i), - (id == android.R.id.progress || id == android.R.id.secondaryProgress)); - } - - LayerDrawable newBg = new LayerDrawable(outDrawables); - - for (int i = 0; i < N; i++) { - newBg.setId(i, background.getId(i)); - } - - return newBg; - - }/* else if (drawable instanceof StateListDrawable) { - StateListDrawable in = (StateListDrawable) drawable; - StateListDrawable out = new StateListDrawable(); - int numStates = in.getStateCount(); - for (int i = 0; i < numStates; i++) { - out.addState(in.getStateSet(i), tileify(in.getStateDrawable(i), clip)); - } - return out; - - }*/ else if (drawable instanceof BitmapDrawable) { - final Bitmap tileBitmap = ((BitmapDrawable) drawable).getBitmap(); - if (mSampleTile == null) { - mSampleTile = tileBitmap; - } - - final ShapeDrawable shapeDrawable = new ShapeDrawable(getDrawableShape()); - - final BitmapShader bitmapShader = new BitmapShader(tileBitmap, - Shader.TileMode.REPEAT, Shader.TileMode.CLAMP); - shapeDrawable.getPaint().setShader(bitmapShader); - - return (clip) ? new ClipDrawable(shapeDrawable, Gravity.LEFT, - ClipDrawable.HORIZONTAL) : shapeDrawable; - } - - return drawable; - } - - Shape getDrawableShape() { - final float[] roundedCorners = new float[] { 5, 5, 5, 5, 5, 5, 5, 5 }; - return new RoundRectShape(roundedCorners, null, null); - } - - /** - * Convert a AnimationDrawable for use as a barberpole animation. - * Each frame of the animation is wrapped in a ClipDrawable and - * given a tiling BitmapShader. - */ - private Drawable tileifyIndeterminate(Drawable drawable) { - if (drawable instanceof AnimationDrawable) { - AnimationDrawable background = (AnimationDrawable) drawable; - final int N = background.getNumberOfFrames(); - AnimationDrawable newBg = new AnimationDrawable(); - newBg.setOneShot(background.isOneShot()); - - for (int i = 0; i < N; i++) { - Drawable frame = tileify(background.getFrame(i), true); - frame.setLevel(10000); - newBg.addFrame(frame, background.getDuration(i)); - } - newBg.setLevel(10000); - drawable = newBg; - } - return drawable; - } - - /** - *

- * Initialize the progress bar's default values: - *

- *
    - *
  • progress = 0
  • - *
  • max = 100
  • - *
  • animation duration = 4000 ms
  • - *
  • indeterminate = false
  • - *
  • behavior = repeat
  • - *
- */ - private void initProgressBar() { - mMax = 100; - mProgress = 0; - mSecondaryProgress = 0; - mIndeterminate = false; - mOnlyIndeterminate = false; - mDuration = 4000; - mBehavior = AlphaAnimation.RESTART; - mMinWidth = 24; - mMaxWidth = 48; - mMinHeight = 24; - mMaxHeight = 48; - } - - /** - *

Indicate whether this progress bar is in indeterminate mode.

- * - * @return true if the progress bar is in indeterminate mode - */ - @ViewDebug.ExportedProperty(category = "progress") - public synchronized boolean isIndeterminate() { - return mIndeterminate; - } - - /** - *

Change the indeterminate mode for this progress bar. In indeterminate - * mode, the progress is ignored and the progress bar shows an infinite - * animation instead.

- * - * If this progress bar's style only supports indeterminate mode (such as the circular - * progress bars), then this will be ignored. - * - * @param indeterminate true to enable the indeterminate mode - */ - public synchronized void setIndeterminate(boolean indeterminate) { - if ((!mOnlyIndeterminate || !mIndeterminate) && indeterminate != mIndeterminate) { - mIndeterminate = indeterminate; - - if (indeterminate) { - // swap between indeterminate and regular backgrounds - mCurrentDrawable = mIndeterminateDrawable; - startAnimation(); - } else { - mCurrentDrawable = mProgressDrawable; - stopAnimation(); - } - } - } - - /** - *

Get the drawable used to draw the progress bar in - * indeterminate mode.

- * - * @return a {@link android.graphics.drawable.Drawable} instance - * - * @see #setIndeterminateDrawable(android.graphics.drawable.Drawable) - * @see #setIndeterminate(boolean) - */ - public Drawable getIndeterminateDrawable() { - return mIndeterminateDrawable; - } - - /** - *

Define the drawable used to draw the progress bar in - * indeterminate mode.

- * - * @param d the new drawable - * - * @see #getIndeterminateDrawable() - * @see #setIndeterminate(boolean) - */ - public void setIndeterminateDrawable(Drawable d) { - if (d != null) { - d.setCallback(this); - } - mIndeterminateDrawable = d; - if (mIndeterminate) { - mCurrentDrawable = d; - postInvalidate(); - } - } - - /** - *

Get the drawable used to draw the progress bar in - * progress mode.

- * - * @return a {@link android.graphics.drawable.Drawable} instance - * - * @see #setProgressDrawable(android.graphics.drawable.Drawable) - * @see #setIndeterminate(boolean) - */ - public Drawable getProgressDrawable() { - return mProgressDrawable; - } - - /** - *

Define the drawable used to draw the progress bar in - * progress mode.

- * - * @param d the new drawable - * - * @see #getProgressDrawable() - * @see #setIndeterminate(boolean) - */ - public void setProgressDrawable(Drawable d) { - boolean needUpdate; - if (mProgressDrawable != null && d != mProgressDrawable) { - mProgressDrawable.setCallback(null); - needUpdate = true; - } else { - needUpdate = false; - } - - if (d != null) { - d.setCallback(this); - - // Make sure the ProgressBar is always tall enough - int drawableHeight = d.getMinimumHeight(); - if (mMaxHeight < drawableHeight) { - mMaxHeight = drawableHeight; - requestLayout(); - } - } - mProgressDrawable = d; - if (!mIndeterminate) { - mCurrentDrawable = d; - postInvalidate(); - } - - if (needUpdate) { - updateDrawableBounds(getWidth(), getHeight()); - updateDrawableState(); - doRefreshProgress(android.R.id.progress, mProgress, false, false); - doRefreshProgress(android.R.id.secondaryProgress, mSecondaryProgress, false, false); - } - } - - /** - * @return The drawable currently used to draw the progress bar - */ - Drawable getCurrentDrawable() { - return mCurrentDrawable; - } - - @Override - protected boolean verifyDrawable(Drawable who) { - return who == mProgressDrawable || who == mIndeterminateDrawable - || super.verifyDrawable(who); - } - - @Override - public void jumpDrawablesToCurrentState() { - super.jumpDrawablesToCurrentState(); - if (mProgressDrawable != null) mProgressDrawable.jumpToCurrentState(); - if (mIndeterminateDrawable != null) mIndeterminateDrawable.jumpToCurrentState(); - } - - @Override - public void postInvalidate() { - if (!mNoInvalidate) { - super.postInvalidate(); - } - } - - private class RefreshProgressRunnable implements Runnable { - - private int mId; - private int mProgress; - private boolean mFromUser; - - RefreshProgressRunnable(int id, int progress, boolean fromUser) { - mId = id; - mProgress = progress; - mFromUser = fromUser; - } - - public void run() { - doRefreshProgress(mId, mProgress, mFromUser, true); - // Put ourselves back in the cache when we are done - mRefreshProgressRunnable = this; - } - - public void setup(int id, int progress, boolean fromUser) { - mId = id; - mProgress = progress; - mFromUser = fromUser; - } - - } - - private synchronized void doRefreshProgress(int id, int progress, boolean fromUser, - boolean callBackToApp) { - float scale = mMax > 0 ? (float) progress / (float) mMax : 0; - final Drawable d = mCurrentDrawable; - if (d != null) { - Drawable progressDrawable = null; - - if (d instanceof LayerDrawable) { - progressDrawable = ((LayerDrawable) d).findDrawableByLayerId(id); - } - - final int level = (int) (scale * MAX_LEVEL); - (progressDrawable != null ? progressDrawable : d).setLevel(level); - } else { - invalidate(); - } - - if (callBackToApp && id == android.R.id.progress) { - onProgressRefresh(scale, fromUser); - } - } - - void onProgressRefresh(float scale, boolean fromUser) { - if (mAccessibilityManager.isEnabled()) { - scheduleAccessibilityEventSender(); - } - } - - private synchronized void refreshProgress(int id, int progress, boolean fromUser) { - if (mUiThreadId == Thread.currentThread().getId()) { - doRefreshProgress(id, progress, fromUser, true); - } else { - RefreshProgressRunnable r; - if (mRefreshProgressRunnable != null) { - // Use cached RefreshProgressRunnable if available - r = mRefreshProgressRunnable; - // Uncache it - mRefreshProgressRunnable = null; - r.setup(id, progress, fromUser); - } else { - // Make a new one - r = new RefreshProgressRunnable(id, progress, fromUser); - } - post(r); - } - } - - /** - *

Set the current progress to the specified value. Does not do anything - * if the progress bar is in indeterminate mode.

- * - * @param progress the new progress, between 0 and {@link #getMax()} - * - * @see #setIndeterminate(boolean) - * @see #isIndeterminate() - * @see #getProgress() - * @see #incrementProgressBy(int) - */ - public synchronized void setProgress(int progress) { - setProgress(progress, false); - } - - synchronized void setProgress(int progress, boolean fromUser) { - if (mIndeterminate) { - return; - } - - if (progress < 0) { - progress = 0; - } - - if (progress > mMax) { - progress = mMax; - } - - if (progress != mProgress) { - mProgress = progress; - refreshProgress(android.R.id.progress, mProgress, fromUser); - } - } - - /** - *

- * Set the current secondary progress to the specified value. Does not do - * anything if the progress bar is in indeterminate mode. - *

- * - * @param secondaryProgress the new secondary progress, between 0 and {@link #getMax()} - * @see #setIndeterminate(boolean) - * @see #isIndeterminate() - * @see #getSecondaryProgress() - * @see #incrementSecondaryProgressBy(int) - */ - public synchronized void setSecondaryProgress(int secondaryProgress) { - if (mIndeterminate) { - return; - } - - if (secondaryProgress < 0) { - secondaryProgress = 0; - } - - if (secondaryProgress > mMax) { - secondaryProgress = mMax; - } - - if (secondaryProgress != mSecondaryProgress) { - mSecondaryProgress = secondaryProgress; - refreshProgress(android.R.id.secondaryProgress, mSecondaryProgress, false); - } - } - - /** - *

Get the progress bar's current level of progress. Return 0 when the - * progress bar is in indeterminate mode.

- * - * @return the current progress, between 0 and {@link #getMax()} - * - * @see #setIndeterminate(boolean) - * @see #isIndeterminate() - * @see #setProgress(int) - * @see #setMax(int) - * @see #getMax() - */ - @ViewDebug.ExportedProperty(category = "progress") - public synchronized int getProgress() { - return mIndeterminate ? 0 : mProgress; - } - - /** - *

Get the progress bar's current level of secondary progress. Return 0 when the - * progress bar is in indeterminate mode.

- * - * @return the current secondary progress, between 0 and {@link #getMax()} - * - * @see #setIndeterminate(boolean) - * @see #isIndeterminate() - * @see #setSecondaryProgress(int) - * @see #setMax(int) - * @see #getMax() - */ - @ViewDebug.ExportedProperty(category = "progress") - public synchronized int getSecondaryProgress() { - return mIndeterminate ? 0 : mSecondaryProgress; - } - - /** - *

Return the upper limit of this progress bar's range.

- * - * @return a positive integer - * - * @see #setMax(int) - * @see #getProgress() - * @see #getSecondaryProgress() - */ - @ViewDebug.ExportedProperty(category = "progress") - public synchronized int getMax() { - return mMax; - } - - /** - *

Set the range of the progress bar to 0...max.

- * - * @param max the upper range of this progress bar - * - * @see #getMax() - * @see #setProgress(int) - * @see #setSecondaryProgress(int) - */ - public synchronized void setMax(int max) { - if (max < 0) { - max = 0; - } - if (max != mMax) { - mMax = max; - postInvalidate(); - - if (mProgress > max) { - mProgress = max; - } - refreshProgress(android.R.id.progress, mProgress, false); - } - } - - /** - *

Increase the progress bar's progress by the specified amount.

- * - * @param diff the amount by which the progress must be increased - * - * @see #setProgress(int) - */ - public synchronized final void incrementProgressBy(int diff) { - setProgress(mProgress + diff); - } - - /** - *

Increase the progress bar's secondary progress by the specified amount.

- * - * @param diff the amount by which the secondary progress must be increased - * - * @see #setSecondaryProgress(int) - */ - public synchronized final void incrementSecondaryProgressBy(int diff) { - setSecondaryProgress(mSecondaryProgress + diff); - } - - /** - *

Start the indeterminate progress animation.

- */ - void startAnimation() { - if (getVisibility() != VISIBLE) { - return; - } - - if (mIndeterminateDrawable instanceof Animatable) { - mShouldStartAnimationDrawable = true; - mAnimation = null; - } else { - if (mInterpolator == null) { - mInterpolator = new LinearInterpolator(); - } - - mTransformation = new Transformation(); - mAnimation = new AlphaAnimation(0.0f, 1.0f); - mAnimation.setRepeatMode(mBehavior); - mAnimation.setRepeatCount(Animation.INFINITE); - mAnimation.setDuration(mDuration); - mAnimation.setInterpolator(mInterpolator); - mAnimation.setStartTime(Animation.START_ON_FIRST_FRAME); - } - postInvalidate(); - } - - /** - *

Stop the indeterminate progress animation.

- */ - void stopAnimation() { - mAnimation = null; - mTransformation = null; - if (mIndeterminateDrawable instanceof Animatable) { - ((Animatable) mIndeterminateDrawable).stop(); - mShouldStartAnimationDrawable = false; - } - postInvalidate(); - } - - /** - * Sets the acceleration curve for the indeterminate animation. - * The interpolator is loaded as a resource from the specified context. - * - * @param context The application environment - * @param resID The resource identifier of the interpolator to load - */ - public void setInterpolator(Context context, int resID) { - setInterpolator(AnimationUtils.loadInterpolator(context, resID)); - } - - /** - * Sets the acceleration curve for the indeterminate animation. - * Defaults to a linear interpolation. - * - * @param interpolator The interpolator which defines the acceleration curve - */ - public void setInterpolator(Interpolator interpolator) { - mInterpolator = interpolator; - } - - /** - * Gets the acceleration curve type for the indeterminate animation. - * - * @return the {@link Interpolator} associated to this animation - */ - public Interpolator getInterpolator() { - return mInterpolator; - } - - @Override - public void setVisibility(int v) { - if (getVisibility() != v) { - super.setVisibility(v); - - if (mIndeterminate) { - // let's be nice with the UI thread - if (v == GONE || v == INVISIBLE) { - stopAnimation(); - } else { - startAnimation(); - } - } - } - } - - @Override - protected void onVisibilityChanged(View changedView, int visibility) { - super.onVisibilityChanged(changedView, visibility); - - if (mIndeterminate) { - // let's be nice with the UI thread - if (visibility == GONE || visibility == INVISIBLE) { - stopAnimation(); - } else { - startAnimation(); - } - } - } - - @Override - public void invalidateDrawable(Drawable dr) { - if (!mInDrawing) { - if (verifyDrawable(dr)) { - final Rect dirty = dr.getBounds(); - final int scrollX = getScrollX() + getPaddingLeft(); - final int scrollY = getScrollY() + getPaddingTop(); - - invalidate(dirty.left + scrollX, dirty.top + scrollY, - dirty.right + scrollX, dirty.bottom + scrollY); - } else { - super.invalidateDrawable(dr); - } - } - } - - /** - * @hide - * - @Override - public int getResolvedLayoutDirection(Drawable who) { - return (who == mProgressDrawable || who == mIndeterminateDrawable) ? - getResolvedLayoutDirection() : super.getResolvedLayoutDirection(who); - } - */ - - @Override - protected void onSizeChanged(int w, int h, int oldw, int oldh) { - updateDrawableBounds(w, h); - } - - private void updateDrawableBounds(int w, int h) { - // onDraw will translate the canvas so we draw starting at 0,0 - int right = w - getPaddingRight() - getPaddingLeft(); - int bottom = h - getPaddingBottom() - getPaddingTop(); - int top = 0; - int left = 0; - - if (mIndeterminateDrawable != null) { - // Aspect ratio logic does not apply to AnimationDrawables - if (mOnlyIndeterminate && !(mIndeterminateDrawable instanceof AnimationDrawable)) { - // Maintain aspect ratio. Certain kinds of animated drawables - // get very confused otherwise. - final int intrinsicWidth = mIndeterminateDrawable.getIntrinsicWidth(); - final int intrinsicHeight = mIndeterminateDrawable.getIntrinsicHeight(); - final float intrinsicAspect = (float) intrinsicWidth / intrinsicHeight; - final float boundAspect = (float) w / h; - if (intrinsicAspect != boundAspect) { - if (boundAspect > intrinsicAspect) { - // New width is larger. Make it smaller to match height. - final int width = (int) (h * intrinsicAspect); - left = (w - width) / 2; - right = left + width; - } else { - // New height is larger. Make it smaller to match width. - final int height = (int) (w * (1 / intrinsicAspect)); - top = (h - height) / 2; - bottom = top + height; - } - } - } - mIndeterminateDrawable.setBounds(0, 0, right - left, bottom - top); - mIndeterminateRealLeft = left; - mIndeterminateRealTop = top; - } - - if (mProgressDrawable != null) { - mProgressDrawable.setBounds(0, 0, right, bottom); - } - } - - @Override - protected synchronized void onDraw(Canvas canvas) { - super.onDraw(canvas); - - Drawable d = mCurrentDrawable; - if (d != null) { - // Translate canvas so a indeterminate circular progress bar with padding - // rotates properly in its animation - canvas.save(); - canvas.translate(getPaddingLeft() + mIndeterminateRealLeft, getPaddingTop() + mIndeterminateRealTop); - long time = getDrawingTime(); - if (mAnimation != null) { - mAnimation.getTransformation(time, mTransformation); - float scale = mTransformation.getAlpha(); - try { - mInDrawing = true; - d.setLevel((int) (scale * MAX_LEVEL)); - } finally { - mInDrawing = false; - } - if (SystemClock.uptimeMillis() - mLastDrawTime >= mAnimationResolution) { - mLastDrawTime = SystemClock.uptimeMillis(); - postInvalidateDelayed(mAnimationResolution); - } - } - d.draw(canvas); - canvas.restore(); - if (mShouldStartAnimationDrawable && d instanceof Animatable) { - ((Animatable) d).start(); - mShouldStartAnimationDrawable = false; - } - } - } - - @Override - protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - Drawable d = mCurrentDrawable; - - int dw = 0; - int dh = 0; - if (d != null) { - dw = Math.max(mMinWidth, Math.min(mMaxWidth, d.getIntrinsicWidth())); - dh = Math.max(mMinHeight, Math.min(mMaxHeight, d.getIntrinsicHeight())); - } - updateDrawableState(); - dw += getPaddingLeft() + getPaddingRight(); - dh += getPaddingTop() + getPaddingBottom(); - - if (IS_HONEYCOMB) { - setMeasuredDimension(View.resolveSizeAndState(dw, widthMeasureSpec, 0), - View.resolveSizeAndState(dh, heightMeasureSpec, 0)); - } else { - setMeasuredDimension(View.resolveSize(dw, widthMeasureSpec), - View.resolveSize(dh, heightMeasureSpec)); - } - } - - @Override - protected void drawableStateChanged() { - super.drawableStateChanged(); - updateDrawableState(); - } - - private void updateDrawableState() { - int[] state = getDrawableState(); - - if (mProgressDrawable != null && mProgressDrawable.isStateful()) { - mProgressDrawable.setState(state); - } - - if (mIndeterminateDrawable != null && mIndeterminateDrawable.isStateful()) { - mIndeterminateDrawable.setState(state); - } - } - - static class SavedState extends BaseSavedState { - int progress; - int secondaryProgress; - - /** - * Constructor called from {@link IcsProgressBar#onSaveInstanceState()} - */ - SavedState(Parcelable superState) { - super(superState); - } - - /** - * Constructor called from {@link #CREATOR} - */ - private SavedState(Parcel in) { - super(in); - progress = in.readInt(); - secondaryProgress = in.readInt(); - } - - @Override - public void writeToParcel(Parcel out, int flags) { - super.writeToParcel(out, flags); - out.writeInt(progress); - out.writeInt(secondaryProgress); - } - - public static final Parcelable.Creator CREATOR - = new Parcelable.Creator() { - public SavedState createFromParcel(Parcel in) { - return new SavedState(in); - } - - public SavedState[] newArray(int size) { - return new SavedState[size]; - } - }; - } - - @Override - public Parcelable onSaveInstanceState() { - // Force our ancestor class to save its state - Parcelable superState = super.onSaveInstanceState(); - SavedState ss = new SavedState(superState); - - ss.progress = mProgress; - ss.secondaryProgress = mSecondaryProgress; - - return ss; - } - - @Override - public void onRestoreInstanceState(Parcelable state) { - SavedState ss = (SavedState) state; - super.onRestoreInstanceState(ss.getSuperState()); - - setProgress(ss.progress); - setSecondaryProgress(ss.secondaryProgress); - } - - @Override - protected void onAttachedToWindow() { - super.onAttachedToWindow(); - if (mIndeterminate) { - startAnimation(); - } - } - - @Override - protected void onDetachedFromWindow() { - if (mIndeterminate) { - stopAnimation(); - } - if(mRefreshProgressRunnable != null) { - removeCallbacks(mRefreshProgressRunnable); - } - if (mAccessibilityEventSender != null) { - removeCallbacks(mAccessibilityEventSender); - } - // This should come after stopAnimation(), otherwise an invalidate message remains in the - // queue, which can prevent the entire view hierarchy from being GC'ed during a rotation - super.onDetachedFromWindow(); - } - - @Override - public void onInitializeAccessibilityEvent(AccessibilityEvent event) { - super.onInitializeAccessibilityEvent(event); - event.setItemCount(mMax); - event.setCurrentItemIndex(mProgress); - } - - /** - * Schedule a command for sending an accessibility event. - *
- * Note: A command is used to ensure that accessibility events - * are sent at most one in a given time frame to save - * system resources while the progress changes quickly. - */ - private void scheduleAccessibilityEventSender() { - if (mAccessibilityEventSender == null) { - mAccessibilityEventSender = new AccessibilityEventSender(); - } else { - removeCallbacks(mAccessibilityEventSender); - } - postDelayed(mAccessibilityEventSender, TIMEOUT_SEND_ACCESSIBILITY_EVENT); - } - - /** - * Command for sending an accessibility event. - */ - private class AccessibilityEventSender implements Runnable { - public void run() { - sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED); - } - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/IcsSpinner.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/IcsSpinner.java deleted file mode 100644 index 038d1e031..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/IcsSpinner.java +++ /dev/null @@ -1,703 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.widget; - -import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; -import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; -import com.actionbarsherlock.R; -import android.content.Context; -import android.content.DialogInterface; -import android.content.DialogInterface.OnClickListener; -import android.content.res.TypedArray; -import android.database.DataSetObserver; -import android.graphics.Rect; -import android.graphics.drawable.Drawable; -import android.util.AttributeSet; -import android.view.Gravity; -import android.view.View; -import android.view.ViewGroup; -import android.widget.AdapterView; -import android.widget.AdapterView.OnItemClickListener; -import android.widget.ListAdapter; -import android.widget.ListView; -import android.widget.PopupWindow; -import android.widget.SpinnerAdapter; - - -/** - * A view that displays one child at a time and lets the user pick among them. - * The items in the Spinner come from the {@link Adapter} associated with - * this view. - * - *

See the Spinner - * tutorial.

- * - * @attr ref android.R.styleable#Spinner_prompt - */ -public class IcsSpinner extends IcsAbsSpinner implements OnClickListener { - //private static final String TAG = "Spinner"; - - // Only measure this many items to get a decent max width. - private static final int MAX_ITEMS_MEASURED = 15; - - /** - * Use a dialog window for selecting spinner options. - */ - //public static final int MODE_DIALOG = 0; - - /** - * Use a dropdown anchored to the Spinner for selecting spinner options. - */ - public static final int MODE_DROPDOWN = 1; - - /** - * Use the theme-supplied value to select the dropdown mode. - */ - //private static final int MODE_THEME = -1; - - private SpinnerPopup mPopup; - private DropDownAdapter mTempAdapter; - int mDropDownWidth; - - private int mGravity; - private boolean mDisableChildrenWhenDisabled; - - private Rect mTempRect = new Rect(); - - public IcsSpinner(Context context, AttributeSet attrs) { - this(context, attrs, R.attr.actionDropDownStyle); - } - - /** - * Construct a new spinner with the given context's theme, the supplied attribute set, - * and default style. - * - * @param context The Context the view is running in, through which it can - * access the current theme, resources, etc. - * @param attrs The attributes of the XML tag that is inflating the view. - * @param defStyle The default style to apply to this view. If 0, no style - * will be applied (beyond what is included in the theme). This may - * either be an attribute resource, whose value will be retrieved - * from the current theme, or an explicit style resource. - */ - public IcsSpinner(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - - TypedArray a = context.obtainStyledAttributes(attrs, - R.styleable.SherlockSpinner, defStyle, 0); - - - DropdownPopup popup = new DropdownPopup(context, attrs, defStyle); - - mDropDownWidth = a.getLayoutDimension( - R.styleable.SherlockSpinner_android_dropDownWidth, - ViewGroup.LayoutParams.WRAP_CONTENT); - popup.setBackgroundDrawable(a.getDrawable( - R.styleable.SherlockSpinner_android_popupBackground)); - final int verticalOffset = a.getDimensionPixelOffset( - R.styleable.SherlockSpinner_android_dropDownVerticalOffset, 0); - if (verticalOffset != 0) { - popup.setVerticalOffset(verticalOffset); - } - - final int horizontalOffset = a.getDimensionPixelOffset( - R.styleable.SherlockSpinner_android_dropDownHorizontalOffset, 0); - if (horizontalOffset != 0) { - popup.setHorizontalOffset(horizontalOffset); - } - - mPopup = popup; - - mGravity = a.getInt(R.styleable.SherlockSpinner_android_gravity, Gravity.CENTER); - - mPopup.setPromptText(a.getString(R.styleable.SherlockSpinner_android_prompt)); - - mDisableChildrenWhenDisabled = true; - - a.recycle(); - - // Base constructor can call setAdapter before we initialize mPopup. - // Finish setting things up if this happened. - if (mTempAdapter != null) { - mPopup.setAdapter(mTempAdapter); - mTempAdapter = null; - } - } - - @Override - public void setEnabled(boolean enabled) { - super.setEnabled(enabled); - if (mDisableChildrenWhenDisabled) { - final int count = getChildCount(); - for (int i = 0; i < count; i++) { - getChildAt(i).setEnabled(enabled); - } - } - } - - /** - * Describes how the selected item view is positioned. Currently only the horizontal component - * is used. The default is determined by the current theme. - * - * @param gravity See {@link android.view.Gravity} - * - * @attr ref android.R.styleable#Spinner_gravity - */ - public void setGravity(int gravity) { - if (mGravity != gravity) { - if ((gravity & Gravity.HORIZONTAL_GRAVITY_MASK) == 0) { - gravity |= Gravity.LEFT; - } - mGravity = gravity; - requestLayout(); - } - } - - @Override - public void setAdapter(SpinnerAdapter adapter) { - super.setAdapter(adapter); - - if (mPopup != null) { - mPopup.setAdapter(new DropDownAdapter(adapter)); - } else { - mTempAdapter = new DropDownAdapter(adapter); - } - } - - @Override - public int getBaseline() { - View child = null; - - if (getChildCount() > 0) { - child = getChildAt(0); - } else if (mAdapter != null && mAdapter.getCount() > 0) { - child = makeAndAddView(0); - mRecycler.put(0, child); - removeAllViewsInLayout(); - } - - if (child != null) { - final int childBaseline = child.getBaseline(); - return childBaseline >= 0 ? child.getTop() + childBaseline : -1; - } else { - return -1; - } - } - - @Override - protected void onDetachedFromWindow() { - super.onDetachedFromWindow(); - - if (mPopup != null && mPopup.isShowing()) { - mPopup.dismiss(); - } - } - - /** - *

A spinner does not support item click events. Calling this method - * will raise an exception.

- * - * @param l this listener will be ignored - */ - @Override - public void setOnItemClickListener(OnItemClickListener l) { - throw new RuntimeException("setOnItemClickListener cannot be used with a spinner."); - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - if (mPopup != null && MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.AT_MOST) { - final int measuredWidth = getMeasuredWidth(); - setMeasuredDimension(Math.min(Math.max(measuredWidth, - measureContentWidth(getAdapter(), getBackground())), - MeasureSpec.getSize(widthMeasureSpec)), - getMeasuredHeight()); - } - } - - /** - * @see android.view.View#onLayout(boolean,int,int,int,int) - * - * Creates and positions all views - * - */ - @Override - protected void onLayout(boolean changed, int l, int t, int r, int b) { - super.onLayout(changed, l, t, r, b); - mInLayout = true; - layout(0, false); - mInLayout = false; - } - - /** - * Creates and positions all views for this Spinner. - * - * @param delta Change in the selected position. +1 moves selection is moving to the right, - * so views are scrolling to the left. -1 means selection is moving to the left. - */ - @Override - void layout(int delta, boolean animate) { - int childrenLeft = mSpinnerPadding.left; - int childrenWidth = getRight() - getLeft() - mSpinnerPadding.left - mSpinnerPadding.right; - - if (mDataChanged) { - handleDataChanged(); - } - - // Handle the empty set by removing all views - if (mItemCount == 0) { - resetList(); - return; - } - - if (mNextSelectedPosition >= 0) { - setSelectedPositionInt(mNextSelectedPosition); - } - - recycleAllViews(); - - // Clear out old views - removeAllViewsInLayout(); - - // Make selected view and position it - mFirstPosition = mSelectedPosition; - View sel = makeAndAddView(mSelectedPosition); - int width = sel.getMeasuredWidth(); - int selectedOffset = childrenLeft; - switch (mGravity & Gravity.HORIZONTAL_GRAVITY_MASK) { - case Gravity.CENTER_HORIZONTAL: - selectedOffset = childrenLeft + (childrenWidth / 2) - (width / 2); - break; - case Gravity.RIGHT: - selectedOffset = childrenLeft + childrenWidth - width; - break; - } - sel.offsetLeftAndRight(selectedOffset); - - // Flush any cached views that did not get reused above - mRecycler.clear(); - - invalidate(); - - checkSelectionChanged(); - - mDataChanged = false; - mNeedSync = false; - setNextSelectedPositionInt(mSelectedPosition); - } - - /** - * Obtain a view, either by pulling an existing view from the recycler or - * by getting a new one from the adapter. If we are animating, make sure - * there is enough information in the view's layout parameters to animate - * from the old to new positions. - * - * @param position Position in the spinner for the view to obtain - * @return A view that has been added to the spinner - */ - private View makeAndAddView(int position) { - - View child; - - if (!mDataChanged) { - child = mRecycler.get(position); - if (child != null) { - // Position the view - setUpChild(child); - - return child; - } - } - - // Nothing found in the recycler -- ask the adapter for a view - child = mAdapter.getView(position, null, this); - - // Position the view - setUpChild(child); - - return child; - } - - /** - * Helper for makeAndAddView to set the position of a view - * and fill out its layout paramters. - * - * @param child The view to position - */ - private void setUpChild(View child) { - - // Respect layout params that are already in the view. Otherwise - // make some up... - ViewGroup.LayoutParams lp = child.getLayoutParams(); - if (lp == null) { - lp = generateDefaultLayoutParams(); - } - - addViewInLayout(child, 0, lp); - - child.setSelected(hasFocus()); - if (mDisableChildrenWhenDisabled) { - child.setEnabled(isEnabled()); - } - - // Get measure specs - int childHeightSpec = ViewGroup.getChildMeasureSpec(mHeightMeasureSpec, - mSpinnerPadding.top + mSpinnerPadding.bottom, lp.height); - int childWidthSpec = ViewGroup.getChildMeasureSpec(mWidthMeasureSpec, - mSpinnerPadding.left + mSpinnerPadding.right, lp.width); - - // Measure child - child.measure(childWidthSpec, childHeightSpec); - - int childLeft; - int childRight; - - // Position vertically based on gravity setting - int childTop = mSpinnerPadding.top - + ((getMeasuredHeight() - mSpinnerPadding.bottom - - mSpinnerPadding.top - child.getMeasuredHeight()) / 2); - int childBottom = childTop + child.getMeasuredHeight(); - - int width = child.getMeasuredWidth(); - childLeft = 0; - childRight = childLeft + width; - - child.layout(childLeft, childTop, childRight, childBottom); - } - - @Override - public boolean performClick() { - boolean handled = super.performClick(); - - if (!handled) { - handled = true; - - if (!mPopup.isShowing()) { - mPopup.show(); - } - } - - return handled; - } - - public void onClick(DialogInterface dialog, int which) { - setSelection(which); - dialog.dismiss(); - } - - /** - * Sets the prompt to display when the dialog is shown. - * @param prompt the prompt to set - */ - public void setPrompt(CharSequence prompt) { - mPopup.setPromptText(prompt); - } - - /** - * Sets the prompt to display when the dialog is shown. - * @param promptId the resource ID of the prompt to display when the dialog is shown - */ - public void setPromptId(int promptId) { - setPrompt(getContext().getText(promptId)); - } - - /** - * @return The prompt to display when the dialog is shown - */ - public CharSequence getPrompt() { - return mPopup.getHintText(); - } - - int measureContentWidth(SpinnerAdapter adapter, Drawable background) { - if (adapter == null) { - return 0; - } - - int width = 0; - View itemView = null; - int itemType = 0; - final int widthMeasureSpec = - MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); - final int heightMeasureSpec = - MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); - - // Make sure the number of items we'll measure is capped. If it's a huge data set - // with wildly varying sizes, oh well. - int start = Math.max(0, getSelectedItemPosition()); - final int end = Math.min(adapter.getCount(), start + MAX_ITEMS_MEASURED); - final int count = end - start; - start = Math.max(0, start - (MAX_ITEMS_MEASURED - count)); - for (int i = start; i < end; i++) { - final int positionType = adapter.getItemViewType(i); - if (positionType != itemType) { - itemType = positionType; - itemView = null; - } - itemView = adapter.getView(i, itemView, this); - if (itemView.getLayoutParams() == null) { - itemView.setLayoutParams(new ViewGroup.LayoutParams( - ViewGroup.LayoutParams.WRAP_CONTENT, - ViewGroup.LayoutParams.WRAP_CONTENT)); - } - itemView.measure(widthMeasureSpec, heightMeasureSpec); - width = Math.max(width, itemView.getMeasuredWidth()); - } - - // Add background padding to measured width - if (background != null) { - background.getPadding(mTempRect); - width += mTempRect.left + mTempRect.right; - } - - return width; - } - - /** - *

Wrapper class for an Adapter. Transforms the embedded Adapter instance - * into a ListAdapter.

- */ - private static class DropDownAdapter implements ListAdapter, SpinnerAdapter { - private SpinnerAdapter mAdapter; - private ListAdapter mListAdapter; - - /** - *

Creates a new ListAdapter wrapper for the specified adapter.

- * - * @param adapter the Adapter to transform into a ListAdapter - */ - public DropDownAdapter(SpinnerAdapter adapter) { - this.mAdapter = adapter; - if (adapter instanceof ListAdapter) { - this.mListAdapter = (ListAdapter) adapter; - } - } - - public int getCount() { - return mAdapter == null ? 0 : mAdapter.getCount(); - } - - public Object getItem(int position) { - return mAdapter == null ? null : mAdapter.getItem(position); - } - - public long getItemId(int position) { - return mAdapter == null ? -1 : mAdapter.getItemId(position); - } - - public View getView(int position, View convertView, ViewGroup parent) { - return getDropDownView(position, convertView, parent); - } - - public View getDropDownView(int position, View convertView, ViewGroup parent) { - return mAdapter == null ? null : - mAdapter.getDropDownView(position, convertView, parent); - } - - public boolean hasStableIds() { - return mAdapter != null && mAdapter.hasStableIds(); - } - - public void registerDataSetObserver(DataSetObserver observer) { - if (mAdapter != null) { - mAdapter.registerDataSetObserver(observer); - } - } - - public void unregisterDataSetObserver(DataSetObserver observer) { - if (mAdapter != null) { - mAdapter.unregisterDataSetObserver(observer); - } - } - - /** - * If the wrapped SpinnerAdapter is also a ListAdapter, delegate this call. - * Otherwise, return true. - */ - public boolean areAllItemsEnabled() { - final ListAdapter adapter = mListAdapter; - if (adapter != null) { - return adapter.areAllItemsEnabled(); - } else { - return true; - } - } - - /** - * If the wrapped SpinnerAdapter is also a ListAdapter, delegate this call. - * Otherwise, return true. - */ - public boolean isEnabled(int position) { - final ListAdapter adapter = mListAdapter; - if (adapter != null) { - return adapter.isEnabled(position); - } else { - return true; - } - } - - public int getItemViewType(int position) { - return 0; - } - - public int getViewTypeCount() { - return 1; - } - - public boolean isEmpty() { - return getCount() == 0; - } - } - - /** - * Implements some sort of popup selection interface for selecting a spinner option. - * Allows for different spinner modes. - */ - private interface SpinnerPopup { - public void setAdapter(ListAdapter adapter); - - /** - * Show the popup - */ - public void show(); - - /** - * Dismiss the popup - */ - public void dismiss(); - - /** - * @return true if the popup is showing, false otherwise. - */ - public boolean isShowing(); - - /** - * Set hint text to be displayed to the user. This should provide - * a description of the choice being made. - * @param hintText Hint text to set. - */ - public void setPromptText(CharSequence hintText); - public CharSequence getHintText(); - } - - /* - private class DialogPopup implements SpinnerPopup, DialogInterface.OnClickListener { - private AlertDialog mPopup; - private ListAdapter mListAdapter; - private CharSequence mPrompt; - - public void dismiss() { - mPopup.dismiss(); - mPopup = null; - } - - public boolean isShowing() { - return mPopup != null ? mPopup.isShowing() : false; - } - - public void setAdapter(ListAdapter adapter) { - mListAdapter = adapter; - } - - public void setPromptText(CharSequence hintText) { - mPrompt = hintText; - } - - public CharSequence getHintText() { - return mPrompt; - } - - public void show() { - AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); - if (mPrompt != null) { - builder.setTitle(mPrompt); - } - mPopup = builder.setSingleChoiceItems(mListAdapter, - getSelectedItemPosition(), this).show(); - } - - public void onClick(DialogInterface dialog, int which) { - setSelection(which); - dismiss(); - } - } - */ - - private class DropdownPopup extends IcsListPopupWindow implements SpinnerPopup { - private CharSequence mHintText; - private ListAdapter mAdapter; - - public DropdownPopup(Context context, AttributeSet attrs, int defStyleRes) { - super(context, attrs, 0, defStyleRes); - - setAnchorView(IcsSpinner.this); - setModal(true); - setPromptPosition(POSITION_PROMPT_ABOVE); - setOnItemClickListener(new OnItemClickListener() { - @SuppressWarnings("rawtypes") - public void onItemClick(AdapterView parent, View v, int position, long id) { - IcsSpinner.this.setSelection(position); - dismiss(); - } - }); - } - - @Override - public void setAdapter(ListAdapter adapter) { - super.setAdapter(adapter); - mAdapter = adapter; - } - - public CharSequence getHintText() { - return mHintText; - } - - public void setPromptText(CharSequence hintText) { - // Hint text is ignored for dropdowns, but maintain it here. - mHintText = hintText; - } - - @Override - public void show() { - final int spinnerPaddingLeft = IcsSpinner.this.getPaddingLeft(); - if (mDropDownWidth == WRAP_CONTENT) { - final int spinnerWidth = IcsSpinner.this.getWidth(); - final int spinnerPaddingRight = IcsSpinner.this.getPaddingRight(); - setContentWidth(Math.max( - measureContentWidth((SpinnerAdapter) mAdapter, getBackground()), - spinnerWidth - spinnerPaddingLeft - spinnerPaddingRight)); - } else if (mDropDownWidth == MATCH_PARENT) { - final int spinnerWidth = IcsSpinner.this.getWidth(); - final int spinnerPaddingRight = IcsSpinner.this.getPaddingRight(); - setContentWidth(spinnerWidth - spinnerPaddingLeft - spinnerPaddingRight); - } else { - setContentWidth(mDropDownWidth); - } - final Drawable background = getBackground(); - int bgOffset = 0; - if (background != null) { - background.getPadding(mTempRect); - bgOffset = -mTempRect.left; - } - setHorizontalOffset(bgOffset + spinnerPaddingLeft); - setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED); - super.show(); - getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE); - setSelection(IcsSpinner.this.getSelectedItemPosition()); - } - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/IcsView.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/IcsView.java deleted file mode 100644 index a7185d082..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/IcsView.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.actionbarsherlock.internal.widget; - -import android.view.View; - -final class IcsView { - //No instances - private IcsView() {} - - /** - * Return only the state bits of {@link #getMeasuredWidthAndState()} - * and {@link #getMeasuredHeightAndState()}, combined into one integer. - * The width component is in the regular bits {@link #MEASURED_STATE_MASK} - * and the height component is at the shifted bits - * {@link #MEASURED_HEIGHT_STATE_SHIFT}>>{@link #MEASURED_STATE_MASK}. - */ - public static int getMeasuredStateInt(View child) { - return (child.getMeasuredWidth()&View.MEASURED_STATE_MASK) - | ((child.getMeasuredHeight()>>View.MEASURED_HEIGHT_STATE_SHIFT) - & (View.MEASURED_STATE_MASK>>View.MEASURED_HEIGHT_STATE_SHIFT)); - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/ScrollingTabContainerView.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/ScrollingTabContainerView.java deleted file mode 100644 index 1a532e06c..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/ScrollingTabContainerView.java +++ /dev/null @@ -1,545 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.actionbarsherlock.internal.widget; - -import android.content.Context; -import android.content.res.Configuration; -import android.content.res.TypedArray; -import android.graphics.drawable.Drawable; -import android.text.TextUtils.TruncateAt; -import android.util.AttributeSet; -import android.view.Gravity; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.view.ViewParent; -import android.view.animation.DecelerateInterpolator; -import android.view.animation.Interpolator; -import android.widget.BaseAdapter; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.ListView; -import com.actionbarsherlock.R; -import com.actionbarsherlock.app.ActionBar; -import com.actionbarsherlock.internal.nineoldandroids.animation.Animator; -import com.actionbarsherlock.internal.nineoldandroids.animation.ObjectAnimator; -import com.actionbarsherlock.internal.nineoldandroids.widget.NineHorizontalScrollView; - -/** - * This widget implements the dynamic action bar tab behavior that can change - * across different configurations or circumstances. - */ -public class ScrollingTabContainerView extends NineHorizontalScrollView - implements IcsAdapterView.OnItemSelectedListener { - //UNUSED private static final String TAG = "ScrollingTabContainerView"; - Runnable mTabSelector; - private TabClickListener mTabClickListener; - - private IcsLinearLayout mTabLayout; - private IcsSpinner mTabSpinner; - private boolean mAllowCollapse; - - private LayoutInflater mInflater; - - int mMaxTabWidth; - private int mContentHeight; - private int mSelectedTabIndex; - - protected Animator mVisibilityAnim; - protected final VisibilityAnimListener mVisAnimListener = new VisibilityAnimListener(); - - private static final /*Time*/Interpolator sAlphaInterpolator = new DecelerateInterpolator(); - - private static final int FADE_DURATION = 200; - - public ScrollingTabContainerView(Context context) { - super(context); - setHorizontalScrollBarEnabled(false); - - TypedArray a = getContext().obtainStyledAttributes(null, R.styleable.SherlockActionBar, - R.attr.actionBarStyle, 0); - setContentHeight(a.getLayoutDimension(R.styleable.SherlockActionBar_height, 0)); - a.recycle(); - - mInflater = LayoutInflater.from(context); - - mTabLayout = createTabLayout(); - addView(mTabLayout, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, - ViewGroup.LayoutParams.MATCH_PARENT)); - } - - @Override - public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - final int widthMode = MeasureSpec.getMode(widthMeasureSpec); - final boolean lockedExpanded = widthMode == MeasureSpec.EXACTLY; - setFillViewport(lockedExpanded); - - final int childCount = mTabLayout.getChildCount(); - if (childCount > 1 && - (widthMode == MeasureSpec.EXACTLY || widthMode == MeasureSpec.AT_MOST)) { - if (childCount > 2) { - mMaxTabWidth = (int) (MeasureSpec.getSize(widthMeasureSpec) * 0.4f); - } else { - mMaxTabWidth = MeasureSpec.getSize(widthMeasureSpec) / 2; - } - } else { - mMaxTabWidth = -1; - } - - heightMeasureSpec = MeasureSpec.makeMeasureSpec(mContentHeight, MeasureSpec.EXACTLY); - - final boolean canCollapse = !lockedExpanded && mAllowCollapse; - - if (canCollapse) { - // See if we should expand - mTabLayout.measure(MeasureSpec.UNSPECIFIED, heightMeasureSpec); - if (mTabLayout.getMeasuredWidth() > MeasureSpec.getSize(widthMeasureSpec)) { - performCollapse(); - } else { - performExpand(); - } - } else { - performExpand(); - } - - final int oldWidth = getMeasuredWidth(); - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - final int newWidth = getMeasuredWidth(); - - if (lockedExpanded && oldWidth != newWidth) { - // Recenter the tab display if we're at a new (scrollable) size. - setTabSelected(mSelectedTabIndex); - } - } - - /** - * Indicates whether this view is collapsed into a dropdown menu instead - * of traditional tabs. - * @return true if showing as a spinner - */ - private boolean isCollapsed() { - return mTabSpinner != null && mTabSpinner.getParent() == this; - } - - public void setAllowCollapse(boolean allowCollapse) { - mAllowCollapse = allowCollapse; - } - - private void performCollapse() { - if (isCollapsed()) return; - - if (mTabSpinner == null) { - mTabSpinner = createSpinner(); - } - removeView(mTabLayout); - addView(mTabSpinner, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, - ViewGroup.LayoutParams.MATCH_PARENT)); - if (mTabSpinner.getAdapter() == null) { - mTabSpinner.setAdapter(new TabAdapter()); - } - if (mTabSelector != null) { - removeCallbacks(mTabSelector); - mTabSelector = null; - } - mTabSpinner.setSelection(mSelectedTabIndex); - } - - private boolean performExpand() { - if (!isCollapsed()) return false; - - removeView(mTabSpinner); - addView(mTabLayout, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, - ViewGroup.LayoutParams.MATCH_PARENT)); - setTabSelected(mTabSpinner.getSelectedItemPosition()); - return false; - } - - public void setTabSelected(int position) { - mSelectedTabIndex = position; - final int tabCount = mTabLayout.getChildCount(); - for (int i = 0; i < tabCount; i++) { - final View child = mTabLayout.getChildAt(i); - final boolean isSelected = i == position; - child.setSelected(isSelected); - if (isSelected) { - animateToTab(position); - } - } - } - - public void setContentHeight(int contentHeight) { - mContentHeight = contentHeight; - requestLayout(); - } - - private IcsLinearLayout createTabLayout() { - final IcsLinearLayout tabLayout = (IcsLinearLayout) LayoutInflater.from(getContext()) - .inflate(R.layout.abs__action_bar_tab_bar_view, null); - tabLayout.setLayoutParams(new LinearLayout.LayoutParams( - LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT)); - return tabLayout; - } - - private IcsSpinner createSpinner() { - final IcsSpinner spinner = new IcsSpinner(getContext(), null, - R.attr.actionDropDownStyle); - spinner.setLayoutParams(new LinearLayout.LayoutParams( - LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT)); - spinner.setOnItemSelectedListener(this); - return spinner; - } - - @Override - protected void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - - // Action bar can change size on configuration changes. - // Reread the desired height from the theme-specified style. - TypedArray a = getContext().obtainStyledAttributes(null, R.styleable.SherlockActionBar, - R.attr.actionBarStyle, 0); - setContentHeight(a.getLayoutDimension(R.styleable.SherlockActionBar_height, 0)); - a.recycle(); - } - - public void animateToVisibility(int visibility) { - if (mVisibilityAnim != null) { - mVisibilityAnim.cancel(); - } - if (visibility == VISIBLE) { - if (getVisibility() != VISIBLE) { - setAlpha(0); - } - ObjectAnimator anim = ObjectAnimator.ofFloat(this, "alpha", 1); - anim.setDuration(FADE_DURATION); - anim.setInterpolator(sAlphaInterpolator); - - anim.addListener(mVisAnimListener.withFinalVisibility(visibility)); - anim.start(); - } else { - ObjectAnimator anim = ObjectAnimator.ofFloat(this, "alpha", 0); - anim.setDuration(FADE_DURATION); - anim.setInterpolator(sAlphaInterpolator); - - anim.addListener(mVisAnimListener.withFinalVisibility(visibility)); - anim.start(); - } - } - - public void animateToTab(final int position) { - final View tabView = mTabLayout.getChildAt(position); - if (mTabSelector != null) { - removeCallbacks(mTabSelector); - } - mTabSelector = new Runnable() { - public void run() { - final int scrollPos = tabView.getLeft() - (getWidth() - tabView.getWidth()) / 2; - smoothScrollTo(scrollPos, 0); - mTabSelector = null; - } - }; - post(mTabSelector); - } - - @Override - public void onAttachedToWindow() { - super.onAttachedToWindow(); - if (mTabSelector != null) { - // Re-post the selector we saved - post(mTabSelector); - } - } - - @Override - public void onDetachedFromWindow() { - super.onDetachedFromWindow(); - if (mTabSelector != null) { - removeCallbacks(mTabSelector); - } - } - - private TabView createTabView(ActionBar.Tab tab, boolean forAdapter) { - //Workaround for not being able to pass a defStyle on pre-3.0 - final TabView tabView = (TabView)mInflater.inflate(R.layout.abs__action_bar_tab, null); - tabView.init(this, tab, forAdapter); - - if (forAdapter) { - tabView.setBackgroundDrawable(null); - tabView.setLayoutParams(new ListView.LayoutParams(ListView.LayoutParams.MATCH_PARENT, - mContentHeight)); - } else { - tabView.setFocusable(true); - - if (mTabClickListener == null) { - mTabClickListener = new TabClickListener(); - } - tabView.setOnClickListener(mTabClickListener); - } - return tabView; - } - - public void addTab(ActionBar.Tab tab, boolean setSelected) { - TabView tabView = createTabView(tab, false); - mTabLayout.addView(tabView, new IcsLinearLayout.LayoutParams(0, - LayoutParams.MATCH_PARENT, 1)); - if (mTabSpinner != null) { - ((TabAdapter) mTabSpinner.getAdapter()).notifyDataSetChanged(); - } - if (setSelected) { - tabView.setSelected(true); - } - if (mAllowCollapse) { - requestLayout(); - } - } - - public void addTab(ActionBar.Tab tab, int position, boolean setSelected) { - final TabView tabView = createTabView(tab, false); - mTabLayout.addView(tabView, position, new IcsLinearLayout.LayoutParams( - 0, LayoutParams.MATCH_PARENT, 1)); - if (mTabSpinner != null) { - ((TabAdapter) mTabSpinner.getAdapter()).notifyDataSetChanged(); - } - if (setSelected) { - tabView.setSelected(true); - } - if (mAllowCollapse) { - requestLayout(); - } - } - - public void updateTab(int position) { - ((TabView) mTabLayout.getChildAt(position)).update(); - if (mTabSpinner != null) { - ((TabAdapter) mTabSpinner.getAdapter()).notifyDataSetChanged(); - } - if (mAllowCollapse) { - requestLayout(); - } - } - - public void removeTabAt(int position) { - mTabLayout.removeViewAt(position); - if (mTabSpinner != null) { - ((TabAdapter) mTabSpinner.getAdapter()).notifyDataSetChanged(); - } - if (mAllowCollapse) { - requestLayout(); - } - } - - public void removeAllTabs() { - mTabLayout.removeAllViews(); - if (mTabSpinner != null) { - ((TabAdapter) mTabSpinner.getAdapter()).notifyDataSetChanged(); - } - if (mAllowCollapse) { - requestLayout(); - } - } - - @Override - public void onItemSelected(IcsAdapterView parent, View view, int position, long id) { - TabView tabView = (TabView) view; - tabView.getTab().select(); - } - - @Override - public void onNothingSelected(IcsAdapterView parent) { - } - - public static class TabView extends LinearLayout { - private ScrollingTabContainerView mParent; - private ActionBar.Tab mTab; - private CapitalizingTextView mTextView; - private ImageView mIconView; - private View mCustomView; - - public TabView(Context context, AttributeSet attrs) { - //TODO super(context, null, R.attr.actionBarTabStyle); - super(context, attrs); - } - - public void init(ScrollingTabContainerView parent, ActionBar.Tab tab, boolean forList) { - mParent = parent; - mTab = tab; - - if (forList) { - setGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL); - } - - update(); - } - - public void bindTab(ActionBar.Tab tab) { - mTab = tab; - update(); - } - - @Override - public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - - // Re-measure if we went beyond our maximum size. - if (mParent.mMaxTabWidth > 0 && getMeasuredWidth() > mParent.mMaxTabWidth) { - super.onMeasure(MeasureSpec.makeMeasureSpec(mParent.mMaxTabWidth, MeasureSpec.EXACTLY), - heightMeasureSpec); - } - } - - public void update() { - final ActionBar.Tab tab = mTab; - final View custom = tab.getCustomView(); - if (custom != null) { - final ViewParent customParent = custom.getParent(); - if (customParent != this) { - if (customParent != null) ((ViewGroup) customParent).removeView(custom); - addView(custom); - } - mCustomView = custom; - if (mTextView != null) mTextView.setVisibility(GONE); - if (mIconView != null) { - mIconView.setVisibility(GONE); - mIconView.setImageDrawable(null); - } - } else { - if (mCustomView != null) { - removeView(mCustomView); - mCustomView = null; - } - - final Drawable icon = tab.getIcon(); - final CharSequence text = tab.getText(); - - if (icon != null) { - if (mIconView == null) { - ImageView iconView = new ImageView(getContext()); - LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT, - LayoutParams.WRAP_CONTENT); - lp.gravity = Gravity.CENTER_VERTICAL; - iconView.setLayoutParams(lp); - addView(iconView, 0); - mIconView = iconView; - } - mIconView.setImageDrawable(icon); - mIconView.setVisibility(VISIBLE); - } else if (mIconView != null) { - mIconView.setVisibility(GONE); - mIconView.setImageDrawable(null); - } - - if (text != null) { - if (mTextView == null) { - CapitalizingTextView textView = new CapitalizingTextView(getContext(), null, - R.attr.actionBarTabTextStyle); - textView.setEllipsize(TruncateAt.END); - LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT, - LayoutParams.WRAP_CONTENT); - lp.gravity = Gravity.CENTER_VERTICAL; - textView.setLayoutParams(lp); - addView(textView); - mTextView = textView; - } - mTextView.setTextCompat(text); - mTextView.setVisibility(VISIBLE); - } else if (mTextView != null) { - mTextView.setVisibility(GONE); - mTextView.setText(null); - } - - if (mIconView != null) { - mIconView.setContentDescription(tab.getContentDescription()); - } - } - } - - public ActionBar.Tab getTab() { - return mTab; - } - } - - private class TabAdapter extends BaseAdapter { - @Override - public int getCount() { - return mTabLayout.getChildCount(); - } - - @Override - public Object getItem(int position) { - return ((TabView) mTabLayout.getChildAt(position)).getTab(); - } - - @Override - public long getItemId(int position) { - return position; - } - - @Override - public View getView(int position, View convertView, ViewGroup parent) { - if (convertView == null) { - convertView = createTabView((ActionBar.Tab) getItem(position), true); - } else { - ((TabView) convertView).bindTab((ActionBar.Tab) getItem(position)); - } - return convertView; - } - } - - private class TabClickListener implements OnClickListener { - public void onClick(View view) { - TabView tabView = (TabView) view; - tabView.getTab().select(); - final int tabCount = mTabLayout.getChildCount(); - for (int i = 0; i < tabCount; i++) { - final View child = mTabLayout.getChildAt(i); - child.setSelected(child == view); - } - } - } - - protected class VisibilityAnimListener implements Animator.AnimatorListener { - private boolean mCanceled = false; - private int mFinalVisibility; - - public VisibilityAnimListener withFinalVisibility(int visibility) { - mFinalVisibility = visibility; - return this; - } - - @Override - public void onAnimationStart(Animator animation) { - setVisibility(VISIBLE); - mVisibilityAnim = animation; - mCanceled = false; - } - - @Override - public void onAnimationEnd(Animator animation) { - if (mCanceled) return; - - mVisibilityAnim = null; - setVisibility(mFinalVisibility); - } - - @Override - public void onAnimationCancel(Animator animation) { - mCanceled = true; - } - - @Override - public void onAnimationRepeat(Animator animation) { - } - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/view/ActionMode.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/view/ActionMode.java deleted file mode 100644 index 81b4cd4d2..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/view/ActionMode.java +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.view; - -import android.view.View; - - -/** - * Represents a contextual mode of the user interface. Action modes can be used for - * modal interactions with content and replace parts of the normal UI until finished. - * Examples of good action modes include selection modes, search, content editing, etc. - */ -public abstract class ActionMode { - private Object mTag; - - /** - * Set a tag object associated with this ActionMode. - * - *

Like the tag available to views, this allows applications to associate arbitrary - * data with an ActionMode for later reference. - * - * @param tag Tag to associate with this ActionMode - * - * @see #getTag() - */ - public void setTag(Object tag) { - mTag = tag; - } - - /** - * Retrieve the tag object associated with this ActionMode. - * - *

Like the tag available to views, this allows applications to associate arbitrary - * data with an ActionMode for later reference. - * - * @return Tag associated with this ActionMode - * - * @see #setTag(Object) - */ - public Object getTag() { - return mTag; - } - - /** - * Set the title of the action mode. This method will have no visible effect if - * a custom view has been set. - * - * @param title Title string to set - * - * @see #setTitle(int) - * @see #setCustomView(View) - */ - public abstract void setTitle(CharSequence title); - - /** - * Set the title of the action mode. This method will have no visible effect if - * a custom view has been set. - * - * @param resId Resource ID of a string to set as the title - * - * @see #setTitle(CharSequence) - * @see #setCustomView(View) - */ - public abstract void setTitle(int resId); - - /** - * Set the subtitle of the action mode. This method will have no visible effect if - * a custom view has been set. - * - * @param subtitle Subtitle string to set - * - * @see #setSubtitle(int) - * @see #setCustomView(View) - */ - public abstract void setSubtitle(CharSequence subtitle); - - /** - * Set the subtitle of the action mode. This method will have no visible effect if - * a custom view has been set. - * - * @param resId Resource ID of a string to set as the subtitle - * - * @see #setSubtitle(CharSequence) - * @see #setCustomView(View) - */ - public abstract void setSubtitle(int resId); - - /** - * Set a custom view for this action mode. The custom view will take the place of - * the title and subtitle. Useful for things like search boxes. - * - * @param view Custom view to use in place of the title/subtitle. - * - * @see #setTitle(CharSequence) - * @see #setSubtitle(CharSequence) - */ - public abstract void setCustomView(View view); - - /** - * Invalidate the action mode and refresh menu content. The mode's - * {@link ActionMode.Callback} will have its - * {@link Callback#onPrepareActionMode(ActionMode, Menu)} method called. - * If it returns true the menu will be scanned for updated content and any relevant changes - * will be reflected to the user. - */ - public abstract void invalidate(); - - /** - * Finish and close this action mode. The action mode's {@link ActionMode.Callback} will - * have its {@link Callback#onDestroyActionMode(ActionMode)} method called. - */ - public abstract void finish(); - - /** - * Returns the menu of actions that this action mode presents. - * @return The action mode's menu. - */ - public abstract Menu getMenu(); - - /** - * Returns the current title of this action mode. - * @return Title text - */ - public abstract CharSequence getTitle(); - - /** - * Returns the current subtitle of this action mode. - * @return Subtitle text - */ - public abstract CharSequence getSubtitle(); - - /** - * Returns the current custom view for this action mode. - * @return The current custom view - */ - public abstract View getCustomView(); - - /** - * Returns a {@link MenuInflater} with the ActionMode's context. - */ - public abstract MenuInflater getMenuInflater(); - - /** - * Returns whether the UI presenting this action mode can take focus or not. - * This is used by internal components within the framework that would otherwise - * present an action mode UI that requires focus, such as an EditText as a custom view. - * - * @return true if the UI used to show this action mode can take focus - * @hide Internal use only - */ - public boolean isUiFocusable() { - return true; - } - - /** - * Callback interface for action modes. Supplied to - * {@link View#startActionMode(Callback)}, a Callback - * configures and handles events raised by a user's interaction with an action mode. - * - *

An action mode's lifecycle is as follows: - *

    - *
  • {@link Callback#onCreateActionMode(ActionMode, Menu)} once on initial - * creation
  • - *
  • {@link Callback#onPrepareActionMode(ActionMode, Menu)} after creation - * and any time the {@link ActionMode} is invalidated
  • - *
  • {@link Callback#onActionItemClicked(ActionMode, MenuItem)} any time a - * contextual action button is clicked
  • - *
  • {@link Callback#onDestroyActionMode(ActionMode)} when the action mode - * is closed
  • - *
- */ - public interface Callback { - /** - * Called when action mode is first created. The menu supplied will be used to - * generate action buttons for the action mode. - * - * @param mode ActionMode being created - * @param menu Menu used to populate action buttons - * @return true if the action mode should be created, false if entering this - * mode should be aborted. - */ - public boolean onCreateActionMode(ActionMode mode, Menu menu); - - /** - * Called to refresh an action mode's action menu whenever it is invalidated. - * - * @param mode ActionMode being prepared - * @param menu Menu used to populate action buttons - * @return true if the menu or action mode was updated, false otherwise. - */ - public boolean onPrepareActionMode(ActionMode mode, Menu menu); - - /** - * Called to report a user click on an action button. - * - * @param mode The current ActionMode - * @param item The item that was clicked - * @return true if this callback handled the event, false if the standard MenuItem - * invocation should continue. - */ - public boolean onActionItemClicked(ActionMode mode, MenuItem item); - - /** - * Called when an action mode is about to be exited and destroyed. - * - * @param mode The current ActionMode being destroyed - */ - public void onDestroyActionMode(ActionMode mode); - } -} \ No newline at end of file diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/view/ActionProvider.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/view/ActionProvider.java deleted file mode 100644 index ae7cb1fe0..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/view/ActionProvider.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.view; - -import android.content.Context; -import android.view.View; - -/** - * This class is a mediator for accomplishing a given task, for example sharing a file. - * It is responsible for creating a view that performs an action that accomplishes the task. - * This class also implements other functions such a performing a default action. - *

- * An ActionProvider can be optionally specified for a {@link MenuItem} and in such a - * case it will be responsible for creating the action view that appears in the - * {@link android.app.ActionBar} as a substitute for the menu item when the item is - * displayed as an action item. Also the provider is responsible for performing a - * default action if a menu item placed on the overflow menu of the ActionBar is - * selected and none of the menu item callbacks has handled the selection. For this - * case the provider can also optionally provide a sub-menu for accomplishing the - * task at hand. - *

- *

- * There are two ways for using an action provider for creating and handling of action views: - *

    - *
  • - * Setting the action provider on a {@link MenuItem} directly by calling - * {@link MenuItem#setActionProvider(ActionProvider)}. - *
  • - *
  • - * Declaring the action provider in the menu XML resource. For example: - *
    - * 
    - *   <item android:id="@+id/my_menu_item"
    - *     android:title="Title"
    - *     android:icon="@drawable/my_menu_item_icon"
    - *     android:showAsAction="ifRoom"
    - *     android:actionProviderClass="foo.bar.SomeActionProvider" />
    - * 
    - * 
    - *
  • - *
- *

- * - * @see MenuItem#setActionProvider(ActionProvider) - * @see MenuItem#getActionProvider() - */ -public abstract class ActionProvider { - private SubUiVisibilityListener mSubUiVisibilityListener; - - /** - * Creates a new instance. - * - * @param context Context for accessing resources. - */ - public ActionProvider(Context context) { - } - - /** - * Factory method for creating new action views. - * - * @return A new action view. - */ - public abstract View onCreateActionView(); - - /** - * Performs an optional default action. - *

- * For the case of an action provider placed in a menu item not shown as an action this - * method is invoked if previous callbacks for processing menu selection has handled - * the event. - *

- *

- * A menu item selection is processed in the following order: - *

    - *
  • - * Receiving a call to {@link MenuItem.OnMenuItemClickListener#onMenuItemClick - * MenuItem.OnMenuItemClickListener.onMenuItemClick}. - *
  • - *
  • - * Receiving a call to {@link android.app.Activity#onOptionsItemSelected(MenuItem) - * Activity.onOptionsItemSelected(MenuItem)} - *
  • - *
  • - * Receiving a call to {@link android.app.Fragment#onOptionsItemSelected(MenuItem) - * Fragment.onOptionsItemSelected(MenuItem)} - *
  • - *
  • - * Launching the {@link android.content.Intent} set via - * {@link MenuItem#setIntent(android.content.Intent) MenuItem.setIntent(android.content.Intent)} - *
  • - *
  • - * Invoking this method. - *
  • - *
- *

- *

- * The default implementation does not perform any action and returns false. - *

- */ - public boolean onPerformDefaultAction() { - return false; - } - - /** - * Determines if this ActionProvider has a submenu associated with it. - * - *

Associated submenus will be shown when an action view is not. This - * provider instance will receive a call to {@link #onPrepareSubMenu(SubMenu)} - * after the call to {@link #onPerformDefaultAction()} and before a submenu is - * displayed to the user. - * - * @return true if the item backed by this provider should have an associated submenu - */ - public boolean hasSubMenu() { - return false; - } - - /** - * Called to prepare an associated submenu for the menu item backed by this ActionProvider. - * - *

if {@link #hasSubMenu()} returns true, this method will be called when the - * menu item is selected to prepare the submenu for presentation to the user. Apps - * may use this to create or alter submenu content right before display. - * - * @param subMenu Submenu that will be displayed - */ - public void onPrepareSubMenu(SubMenu subMenu) { - } - - /** - * Notify the system that the visibility of an action view's sub-UI such as - * an anchored popup has changed. This will affect how other system - * visibility notifications occur. - * - * @hide Pending future API approval - */ - public void subUiVisibilityChanged(boolean isVisible) { - if (mSubUiVisibilityListener != null) { - mSubUiVisibilityListener.onSubUiVisibilityChanged(isVisible); - } - } - - /** - * @hide Internal use only - */ - public void setSubUiVisibilityListener(SubUiVisibilityListener listener) { - mSubUiVisibilityListener = listener; - } - - /** - * @hide Internal use only - */ - public interface SubUiVisibilityListener { - public void onSubUiVisibilityChanged(boolean isVisible); - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/view/CollapsibleActionView.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/view/CollapsibleActionView.java deleted file mode 100644 index 43281b013..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/view/CollapsibleActionView.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.view; - -/** - * When a {@link View} implements this interface it will receive callbacks - * when expanded or collapsed as an action view alongside the optional, - * app-specified callbacks to {@link OnActionExpandListener}. - * - *

See {@link MenuItem} for more information about action views. - * See {@link android.app.ActionBar} for more information about the action bar. - */ -public interface CollapsibleActionView { - /** - * Called when this view is expanded as an action view. - * See {@link MenuItem#expandActionView()}. - */ - public void onActionViewExpanded(); - - /** - * Called when this view is collapsed as an action view. - * See {@link MenuItem#collapseActionView()}. - */ - public void onActionViewCollapsed(); -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/view/Menu.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/view/Menu.java deleted file mode 100644 index 951f4ccef..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/view/Menu.java +++ /dev/null @@ -1,447 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.view; - -import android.content.ComponentName; -import android.content.Intent; -import android.view.KeyEvent; - -/** - * Interface for managing the items in a menu. - *

- * By default, every Activity supports an options menu of actions or options. - * You can add items to this menu and handle clicks on your additions. The - * easiest way of adding menu items is inflating an XML file into the - * {@link Menu} via {@link MenuInflater}. The easiest way of attaching code to - * clicks is via {@link Activity#onOptionsItemSelected(MenuItem)} and - * {@link Activity#onContextItemSelected(MenuItem)}. - *

- * Different menu types support different features: - *

    - *
  1. Context menus: Do not support item shortcuts and item icons. - *
  2. Options menus: The icon menus do not support item check - * marks and only show the item's - * {@link MenuItem#setTitleCondensed(CharSequence) condensed title}. The - * expanded menus (only available if six or more menu items are visible, - * reached via the 'More' item in the icon menu) do not show item icons, and - * item check marks are discouraged. - *
  3. Sub menus: Do not support item icons, or nested sub menus. - *
- * - *
- *

Developer Guides

- *

For more information about creating menus, read the - * Menus developer guide.

- *
- */ -public interface Menu { - - /** - * This is the part of an order integer that the user can provide. - * @hide - */ - static final int USER_MASK = 0x0000ffff; - /** - * Bit shift of the user portion of the order integer. - * @hide - */ - static final int USER_SHIFT = 0; - - /** - * This is the part of an order integer that supplies the category of the - * item. - * @hide - */ - static final int CATEGORY_MASK = 0xffff0000; - /** - * Bit shift of the category portion of the order integer. - * @hide - */ - static final int CATEGORY_SHIFT = 16; - - /** - * Value to use for group and item identifier integers when you don't care - * about them. - */ - static final int NONE = 0; - - /** - * First value for group and item identifier integers. - */ - static final int FIRST = 1; - - // Implementation note: Keep these CATEGORY_* in sync with the category enum - // in attrs.xml - - /** - * Category code for the order integer for items/groups that are part of a - * container -- or/add this with your base value. - */ - static final int CATEGORY_CONTAINER = 0x00010000; - - /** - * Category code for the order integer for items/groups that are provided by - * the system -- or/add this with your base value. - */ - static final int CATEGORY_SYSTEM = 0x00020000; - - /** - * Category code for the order integer for items/groups that are - * user-supplied secondary (infrequently used) options -- or/add this with - * your base value. - */ - static final int CATEGORY_SECONDARY = 0x00030000; - - /** - * Category code for the order integer for items/groups that are - * alternative actions on the data that is currently displayed -- or/add - * this with your base value. - */ - static final int CATEGORY_ALTERNATIVE = 0x00040000; - - /** - * Flag for {@link #addIntentOptions}: if set, do not automatically remove - * any existing menu items in the same group. - */ - static final int FLAG_APPEND_TO_GROUP = 0x0001; - - /** - * Flag for {@link #performShortcut}: if set, do not close the menu after - * executing the shortcut. - */ - static final int FLAG_PERFORM_NO_CLOSE = 0x0001; - - /** - * Flag for {@link #performShortcut(int, KeyEvent, int)}: if set, always - * close the menu after executing the shortcut. Closing the menu also resets - * the prepared state. - */ - static final int FLAG_ALWAYS_PERFORM_CLOSE = 0x0002; - - /** - * Add a new item to the menu. This item displays the given title for its - * label. - * - * @param title The text to display for the item. - * @return The newly added menu item. - */ - public MenuItem add(CharSequence title); - - /** - * Add a new item to the menu. This item displays the given title for its - * label. - * - * @param titleRes Resource identifier of title string. - * @return The newly added menu item. - */ - public MenuItem add(int titleRes); - - /** - * Add a new item to the menu. This item displays the given title for its - * label. - * - * @param groupId The group identifier that this item should be part of. - * This can be used to define groups of items for batch state - * changes. Normally use {@link #NONE} if an item should not be in a - * group. - * @param itemId Unique item ID. Use {@link #NONE} if you do not need a - * unique ID. - * @param order The order for the item. Use {@link #NONE} if you do not care - * about the order. See {@link MenuItem#getOrder()}. - * @param title The text to display for the item. - * @return The newly added menu item. - */ - public MenuItem add(int groupId, int itemId, int order, CharSequence title); - - /** - * Variation on {@link #add(int, int, int, CharSequence)} that takes a - * string resource identifier instead of the string itself. - * - * @param groupId The group identifier that this item should be part of. - * This can also be used to define groups of items for batch state - * changes. Normally use {@link #NONE} if an item should not be in a - * group. - * @param itemId Unique item ID. Use {@link #NONE} if you do not need a - * unique ID. - * @param order The order for the item. Use {@link #NONE} if you do not care - * about the order. See {@link MenuItem#getOrder()}. - * @param titleRes Resource identifier of title string. - * @return The newly added menu item. - */ - public MenuItem add(int groupId, int itemId, int order, int titleRes); - - /** - * Add a new sub-menu to the menu. This item displays the given title for - * its label. To modify other attributes on the submenu's menu item, use - * {@link SubMenu#getItem()}. - * - * @param title The text to display for the item. - * @return The newly added sub-menu - */ - SubMenu addSubMenu(final CharSequence title); - - /** - * Add a new sub-menu to the menu. This item displays the given title for - * its label. To modify other attributes on the submenu's menu item, use - * {@link SubMenu#getItem()}. - * - * @param titleRes Resource identifier of title string. - * @return The newly added sub-menu - */ - SubMenu addSubMenu(final int titleRes); - - /** - * Add a new sub-menu to the menu. This item displays the given - * title for its label. To modify other attributes on the - * submenu's menu item, use {@link SubMenu#getItem()}. - *

- * Note that you can only have one level of sub-menus, i.e. you cannnot add - * a subMenu to a subMenu: An {@link UnsupportedOperationException} will be - * thrown if you try. - * - * @param groupId The group identifier that this item should be part of. - * This can also be used to define groups of items for batch state - * changes. Normally use {@link #NONE} if an item should not be in a - * group. - * @param itemId Unique item ID. Use {@link #NONE} if you do not need a - * unique ID. - * @param order The order for the item. Use {@link #NONE} if you do not care - * about the order. See {@link MenuItem#getOrder()}. - * @param title The text to display for the item. - * @return The newly added sub-menu - */ - SubMenu addSubMenu(final int groupId, final int itemId, int order, final CharSequence title); - - /** - * Variation on {@link #addSubMenu(int, int, int, CharSequence)} that takes - * a string resource identifier for the title instead of the string itself. - * - * @param groupId The group identifier that this item should be part of. - * This can also be used to define groups of items for batch state - * changes. Normally use {@link #NONE} if an item should not be in a group. - * @param itemId Unique item ID. Use {@link #NONE} if you do not need a unique ID. - * @param order The order for the item. Use {@link #NONE} if you do not care about the - * order. See {@link MenuItem#getOrder()}. - * @param titleRes Resource identifier of title string. - * @return The newly added sub-menu - */ - SubMenu addSubMenu(int groupId, int itemId, int order, int titleRes); - - /** - * Add a group of menu items corresponding to actions that can be performed - * for a particular Intent. The Intent is most often configured with a null - * action, the data that the current activity is working with, and includes - * either the {@link Intent#CATEGORY_ALTERNATIVE} or - * {@link Intent#CATEGORY_SELECTED_ALTERNATIVE} to find activities that have - * said they would like to be included as optional action. You can, however, - * use any Intent you want. - * - *

- * See {@link android.content.pm.PackageManager#queryIntentActivityOptions} - * for more * details on the caller, specifics, and - * intent arguments. The list returned by that function is used - * to populate the resulting menu items. - * - *

- * All of the menu items of possible options for the intent will be added - * with the given group and id. You can use the group to control ordering of - * the items in relation to other items in the menu. Normally this function - * will automatically remove any existing items in the menu in the same - * group and place a divider above and below the added items; this behavior - * can be modified with the flags parameter. For each of the - * generated items {@link MenuItem#setIntent} is called to associate the - * appropriate Intent with the item; this means the activity will - * automatically be started for you without having to do anything else. - * - * @param groupId The group identifier that the items should be part of. - * This can also be used to define groups of items for batch state - * changes. Normally use {@link #NONE} if the items should not be in - * a group. - * @param itemId Unique item ID. Use {@link #NONE} if you do not need a - * unique ID. - * @param order The order for the items. Use {@link #NONE} if you do not - * care about the order. See {@link MenuItem#getOrder()}. - * @param caller The current activity component name as defined by - * queryIntentActivityOptions(). - * @param specifics Specific items to place first as defined by - * queryIntentActivityOptions(). - * @param intent Intent describing the kinds of items to populate in the - * list as defined by queryIntentActivityOptions(). - * @param flags Additional options controlling how the items are added. - * @param outSpecificItems Optional array in which to place the menu items - * that were generated for each of the specifics that were - * requested. Entries may be null if no activity was found for that - * specific action. - * @return The number of menu items that were added. - * - * @see #FLAG_APPEND_TO_GROUP - * @see MenuItem#setIntent - * @see android.content.pm.PackageManager#queryIntentActivityOptions - */ - public int addIntentOptions(int groupId, int itemId, int order, - ComponentName caller, Intent[] specifics, - Intent intent, int flags, MenuItem[] outSpecificItems); - - /** - * Remove the item with the given identifier. - * - * @param id The item to be removed. If there is no item with this - * identifier, nothing happens. - */ - public void removeItem(int id); - - /** - * Remove all items in the given group. - * - * @param groupId The group to be removed. If there are no items in this - * group, nothing happens. - */ - public void removeGroup(int groupId); - - /** - * Remove all existing items from the menu, leaving it empty as if it had - * just been created. - */ - public void clear(); - - /** - * Control whether a particular group of items can show a check mark. This - * is similar to calling {@link MenuItem#setCheckable} on all of the menu items - * with the given group identifier, but in addition you can control whether - * this group contains a mutually-exclusive set items. This should be called - * after the items of the group have been added to the menu. - * - * @param group The group of items to operate on. - * @param checkable Set to true to allow a check mark, false to - * disallow. The default is false. - * @param exclusive If set to true, only one item in this group can be - * checked at a time; checking an item will automatically - * uncheck all others in the group. If set to false, each - * item can be checked independently of the others. - * - * @see MenuItem#setCheckable - * @see MenuItem#setChecked - */ - public void setGroupCheckable(int group, boolean checkable, boolean exclusive); - - /** - * Show or hide all menu items that are in the given group. - * - * @param group The group of items to operate on. - * @param visible If true the items are visible, else they are hidden. - * - * @see MenuItem#setVisible - */ - public void setGroupVisible(int group, boolean visible); - - /** - * Enable or disable all menu items that are in the given group. - * - * @param group The group of items to operate on. - * @param enabled If true the items will be enabled, else they will be disabled. - * - * @see MenuItem#setEnabled - */ - public void setGroupEnabled(int group, boolean enabled); - - /** - * Return whether the menu currently has item items that are visible. - * - * @return True if there is one or more item visible, - * else false. - */ - public boolean hasVisibleItems(); - - /** - * Return the menu item with a particular identifier. - * - * @param id The identifier to find. - * - * @return The menu item object, or null if there is no item with - * this identifier. - */ - public MenuItem findItem(int id); - - /** - * Get the number of items in the menu. Note that this will change any - * times items are added or removed from the menu. - * - * @return The item count. - */ - public int size(); - - /** - * Gets the menu item at the given index. - * - * @param index The index of the menu item to return. - * @return The menu item. - * @exception IndexOutOfBoundsException - * when {@code index < 0 || >= size()} - */ - public MenuItem getItem(int index); - - /** - * Closes the menu, if open. - */ - public void close(); - - /** - * Execute the menu item action associated with the given shortcut - * character. - * - * @param keyCode The keycode of the shortcut key. - * @param event Key event message. - * @param flags Additional option flags or 0. - * - * @return If the given shortcut exists and is shown, returns - * true; else returns false. - * - * @see #FLAG_PERFORM_NO_CLOSE - */ - public boolean performShortcut(int keyCode, KeyEvent event, int flags); - - /** - * Is a keypress one of the defined shortcut keys for this window. - * @param keyCode the key code from {@link KeyEvent} to check. - * @param event the {@link KeyEvent} to use to help check. - */ - boolean isShortcutKey(int keyCode, KeyEvent event); - - /** - * Execute the menu item action associated with the given menu identifier. - * - * @param id Identifier associated with the menu item. - * @param flags Additional option flags or 0. - * - * @return If the given identifier exists and is shown, returns - * true; else returns false. - * - * @see #FLAG_PERFORM_NO_CLOSE - */ - public boolean performIdentifierAction(int id, int flags); - - - /** - * Control whether the menu should be running in qwerty mode (alphabetic - * shortcuts) or 12-key mode (numeric shortcuts). - * - * @param isQwerty If true the menu will use alphabetic shortcuts; else it - * will use numeric shortcuts. - */ - public void setQwertyMode(boolean isQwerty); -} - diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/view/MenuInflater.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/view/MenuInflater.java deleted file mode 100644 index 969459749..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/view/MenuInflater.java +++ /dev/null @@ -1,472 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * 2011 Jake Wharton - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.view; - -import java.io.IOException; -import java.lang.reflect.Constructor; -import java.lang.reflect.Method; -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; -import android.content.Context; -import android.content.res.TypedArray; -import android.content.res.XmlResourceParser; -import android.util.AttributeSet; -import android.util.Log; -import android.util.TypedValue; -import android.util.Xml; -import android.view.InflateException; -import android.view.View; - -import com.actionbarsherlock.R; -import com.actionbarsherlock.internal.view.menu.MenuItemImpl; - -/** - * This class is used to instantiate menu XML files into Menu objects. - *

- * For performance reasons, menu inflation relies heavily on pre-processing of - * XML files that is done at build time. Therefore, it is not currently possible - * to use MenuInflater with an XmlPullParser over a plain XML file at runtime; - * it only works with an XmlPullParser returned from a compiled resource (R. - * something file.) - */ -public class MenuInflater { - private static final String LOG_TAG = "MenuInflater"; - - /** Menu tag name in XML. */ - private static final String XML_MENU = "menu"; - - /** Group tag name in XML. */ - private static final String XML_GROUP = "group"; - - /** Item tag name in XML. */ - private static final String XML_ITEM = "item"; - - private static final int NO_ID = 0; - - private static final Class[] ACTION_VIEW_CONSTRUCTOR_SIGNATURE = new Class[] {Context.class}; - - private static final Class[] ACTION_PROVIDER_CONSTRUCTOR_SIGNATURE = ACTION_VIEW_CONSTRUCTOR_SIGNATURE; - - private final Object[] mActionViewConstructorArguments; - - private final Object[] mActionProviderConstructorArguments; - - private Context mContext; - - /** - * Constructs a menu inflater. - * - * @see Activity#getMenuInflater() - */ - public MenuInflater(Context context) { - mContext = context; - mActionViewConstructorArguments = new Object[] {context}; - mActionProviderConstructorArguments = mActionViewConstructorArguments; - } - - /** - * Inflate a menu hierarchy from the specified XML resource. Throws - * {@link InflateException} if there is an error. - * - * @param menuRes Resource ID for an XML layout resource to load (e.g., - * R.menu.main_activity) - * @param menu The Menu to inflate into. The items and submenus will be - * added to this Menu. - */ - public void inflate(int menuRes, Menu menu) { - XmlResourceParser parser = null; - try { - parser = mContext.getResources().getLayout(menuRes); - AttributeSet attrs = Xml.asAttributeSet(parser); - - parseMenu(parser, attrs, menu); - } catch (XmlPullParserException e) { - throw new InflateException("Error inflating menu XML", e); - } catch (IOException e) { - throw new InflateException("Error inflating menu XML", e); - } finally { - if (parser != null) parser.close(); - } - } - - /** - * Called internally to fill the given menu. If a sub menu is seen, it will - * call this recursively. - */ - private void parseMenu(XmlPullParser parser, AttributeSet attrs, Menu menu) - throws XmlPullParserException, IOException { - MenuState menuState = new MenuState(menu); - - int eventType = parser.getEventType(); - String tagName; - boolean lookingForEndOfUnknownTag = false; - String unknownTagName = null; - - // This loop will skip to the menu start tag - do { - if (eventType == XmlPullParser.START_TAG) { - tagName = parser.getName(); - if (tagName.equals(XML_MENU)) { - // Go to next tag - eventType = parser.next(); - break; - } - - throw new RuntimeException("Expecting menu, got " + tagName); - } - eventType = parser.next(); - } while (eventType != XmlPullParser.END_DOCUMENT); - - boolean reachedEndOfMenu = false; - while (!reachedEndOfMenu) { - switch (eventType) { - case XmlPullParser.START_TAG: - if (lookingForEndOfUnknownTag) { - break; - } - - tagName = parser.getName(); - if (tagName.equals(XML_GROUP)) { - menuState.readGroup(attrs); - } else if (tagName.equals(XML_ITEM)) { - menuState.readItem(attrs); - } else if (tagName.equals(XML_MENU)) { - // A menu start tag denotes a submenu for an item - SubMenu subMenu = menuState.addSubMenuItem(); - - // Parse the submenu into returned SubMenu - parseMenu(parser, attrs, subMenu); - } else { - lookingForEndOfUnknownTag = true; - unknownTagName = tagName; - } - break; - - case XmlPullParser.END_TAG: - tagName = parser.getName(); - if (lookingForEndOfUnknownTag && tagName.equals(unknownTagName)) { - lookingForEndOfUnknownTag = false; - unknownTagName = null; - } else if (tagName.equals(XML_GROUP)) { - menuState.resetGroup(); - } else if (tagName.equals(XML_ITEM)) { - // Add the item if it hasn't been added (if the item was - // a submenu, it would have been added already) - if (!menuState.hasAddedItem()) { - if (menuState.itemActionProvider != null && - menuState.itemActionProvider.hasSubMenu()) { - menuState.addSubMenuItem(); - } else { - menuState.addItem(); - } - } - } else if (tagName.equals(XML_MENU)) { - reachedEndOfMenu = true; - } - break; - - case XmlPullParser.END_DOCUMENT: - throw new RuntimeException("Unexpected end of document"); - } - - eventType = parser.next(); - } - } - - private static class InflatedOnMenuItemClickListener - implements MenuItem.OnMenuItemClickListener { - private static final Class[] PARAM_TYPES = new Class[] { MenuItem.class }; - - private Context mContext; - private Method mMethod; - - public InflatedOnMenuItemClickListener(Context context, String methodName) { - mContext = context; - Class c = context.getClass(); - try { - mMethod = c.getMethod(methodName, PARAM_TYPES); - } catch (Exception e) { - InflateException ex = new InflateException( - "Couldn't resolve menu item onClick handler " + methodName + - " in class " + c.getName()); - ex.initCause(e); - throw ex; - } - } - - public boolean onMenuItemClick(MenuItem item) { - try { - if (mMethod.getReturnType() == Boolean.TYPE) { - return (Boolean) mMethod.invoke(mContext, item); - } else { - mMethod.invoke(mContext, item); - return true; - } - } catch (Exception e) { - throw new RuntimeException(e); - } - } - } - - /** - * State for the current menu. - *

- * Groups can not be nested unless there is another menu (which will have - * its state class). - */ - private class MenuState { - private Menu menu; - - /* - * Group state is set on items as they are added, allowing an item to - * override its group state. (As opposed to set on items at the group end tag.) - */ - private int groupId; - private int groupCategory; - private int groupOrder; - private int groupCheckable; - private boolean groupVisible; - private boolean groupEnabled; - - private boolean itemAdded; - private int itemId; - private int itemCategoryOrder; - private CharSequence itemTitle; - private CharSequence itemTitleCondensed; - private int itemIconResId; - private char itemAlphabeticShortcut; - private char itemNumericShortcut; - /** - * Sync to attrs.xml enum: - * - 0: none - * - 1: all - * - 2: exclusive - */ - private int itemCheckable; - private boolean itemChecked; - private boolean itemVisible; - private boolean itemEnabled; - - /** - * Sync to attrs.xml enum, values in MenuItem: - * - 0: never - * - 1: ifRoom - * - 2: always - * - -1: Safe sentinel for "no value". - */ - private int itemShowAsAction; - - private int itemActionViewLayout; - private String itemActionViewClassName; - private String itemActionProviderClassName; - - private String itemListenerMethodName; - - private ActionProvider itemActionProvider; - - private static final int defaultGroupId = NO_ID; - private static final int defaultItemId = NO_ID; - private static final int defaultItemCategory = 0; - private static final int defaultItemOrder = 0; - private static final int defaultItemCheckable = 0; - private static final boolean defaultItemChecked = false; - private static final boolean defaultItemVisible = true; - private static final boolean defaultItemEnabled = true; - - public MenuState(final Menu menu) { - this.menu = menu; - - resetGroup(); - } - - public void resetGroup() { - groupId = defaultGroupId; - groupCategory = defaultItemCategory; - groupOrder = defaultItemOrder; - groupCheckable = defaultItemCheckable; - groupVisible = defaultItemVisible; - groupEnabled = defaultItemEnabled; - } - - /** - * Called when the parser is pointing to a group tag. - */ - public void readGroup(AttributeSet attrs) { - TypedArray a = mContext.obtainStyledAttributes(attrs, - R.styleable.SherlockMenuGroup); - - groupId = a.getResourceId(R.styleable.SherlockMenuGroup_android_id, defaultGroupId); - groupCategory = a.getInt(R.styleable.SherlockMenuGroup_android_menuCategory, defaultItemCategory); - groupOrder = a.getInt(R.styleable.SherlockMenuGroup_android_orderInCategory, defaultItemOrder); - groupCheckable = a.getInt(R.styleable.SherlockMenuGroup_android_checkableBehavior, defaultItemCheckable); - groupVisible = a.getBoolean(R.styleable.SherlockMenuGroup_android_visible, defaultItemVisible); - groupEnabled = a.getBoolean(R.styleable.SherlockMenuGroup_android_enabled, defaultItemEnabled); - - a.recycle(); - } - - /** - * Called when the parser is pointing to an item tag. - */ - public void readItem(AttributeSet attrs) { - TypedArray a = mContext.obtainStyledAttributes(attrs, - R.styleable.SherlockMenuItem); - - // Inherit attributes from the group as default value - itemId = a.getResourceId(R.styleable.SherlockMenuItem_android_id, defaultItemId); - final int category = a.getInt(R.styleable.SherlockMenuItem_android_menuCategory, groupCategory); - final int order = a.getInt(R.styleable.SherlockMenuItem_android_orderInCategory, groupOrder); - itemCategoryOrder = (category & Menu.CATEGORY_MASK) | (order & Menu.USER_MASK); - itemTitle = a.getText(R.styleable.SherlockMenuItem_android_title); - itemTitleCondensed = a.getText(R.styleable.SherlockMenuItem_android_titleCondensed); - itemIconResId = a.getResourceId(R.styleable.SherlockMenuItem_android_icon, 0); - itemAlphabeticShortcut = - getShortcut(a.getString(R.styleable.SherlockMenuItem_android_alphabeticShortcut)); - itemNumericShortcut = - getShortcut(a.getString(R.styleable.SherlockMenuItem_android_numericShortcut)); - if (a.hasValue(R.styleable.SherlockMenuItem_android_checkable)) { - // Item has attribute checkable, use it - itemCheckable = a.getBoolean(R.styleable.SherlockMenuItem_android_checkable, false) ? 1 : 0; - } else { - // Item does not have attribute, use the group's (group can have one more state - // for checkable that represents the exclusive checkable) - itemCheckable = groupCheckable; - } - - itemChecked = a.getBoolean(R.styleable.SherlockMenuItem_android_checked, defaultItemChecked); - itemVisible = a.getBoolean(R.styleable.SherlockMenuItem_android_visible, groupVisible); - itemEnabled = a.getBoolean(R.styleable.SherlockMenuItem_android_enabled, groupEnabled); - - TypedValue value = new TypedValue(); - a.getValue(R.styleable.SherlockMenuItem_android_showAsAction, value); - itemShowAsAction = value.type == TypedValue.TYPE_INT_HEX ? value.data : -1; - - itemListenerMethodName = a.getString(R.styleable.SherlockMenuItem_android_onClick); - itemActionViewLayout = a.getResourceId(R.styleable.SherlockMenuItem_android_actionLayout, 0); - itemActionViewClassName = a.getString(R.styleable.SherlockMenuItem_android_actionViewClass); - itemActionProviderClassName = a.getString(R.styleable.SherlockMenuItem_android_actionProviderClass); - - final boolean hasActionProvider = itemActionProviderClassName != null; - if (hasActionProvider && itemActionViewLayout == 0 && itemActionViewClassName == null) { - itemActionProvider = newInstance(itemActionProviderClassName, - ACTION_PROVIDER_CONSTRUCTOR_SIGNATURE, - mActionProviderConstructorArguments); - } else { - if (hasActionProvider) { - Log.w(LOG_TAG, "Ignoring attribute 'actionProviderClass'." - + " Action view already specified."); - } - itemActionProvider = null; - } - - a.recycle(); - - itemAdded = false; - } - - private char getShortcut(String shortcutString) { - if (shortcutString == null) { - return 0; - } else { - return shortcutString.charAt(0); - } - } - - private void setItem(MenuItem item) { - item.setChecked(itemChecked) - .setVisible(itemVisible) - .setEnabled(itemEnabled) - .setCheckable(itemCheckable >= 1) - .setTitleCondensed(itemTitleCondensed) - .setIcon(itemIconResId) - .setAlphabeticShortcut(itemAlphabeticShortcut) - .setNumericShortcut(itemNumericShortcut); - - if (itemShowAsAction >= 0) { - item.setShowAsAction(itemShowAsAction); - } - - if (itemListenerMethodName != null) { - if (mContext.isRestricted()) { - throw new IllegalStateException("The android:onClick attribute cannot " - + "be used within a restricted context"); - } - item.setOnMenuItemClickListener( - new InflatedOnMenuItemClickListener(mContext, itemListenerMethodName)); - } - - if (itemCheckable >= 2) { - if (item instanceof MenuItemImpl) { - MenuItemImpl impl = (MenuItemImpl) item; - impl.setExclusiveCheckable(true); - } else { - menu.setGroupCheckable(groupId, true, true); - } - } - - boolean actionViewSpecified = false; - if (itemActionViewClassName != null) { - View actionView = (View) newInstance(itemActionViewClassName, - ACTION_VIEW_CONSTRUCTOR_SIGNATURE, mActionViewConstructorArguments); - item.setActionView(actionView); - actionViewSpecified = true; - } - if (itemActionViewLayout > 0) { - if (!actionViewSpecified) { - item.setActionView(itemActionViewLayout); - actionViewSpecified = true; - } else { - Log.w(LOG_TAG, "Ignoring attribute 'itemActionViewLayout'." - + " Action view already specified."); - } - } - if (itemActionProvider != null) { - item.setActionProvider(itemActionProvider); - } - } - - public void addItem() { - itemAdded = true; - setItem(menu.add(groupId, itemId, itemCategoryOrder, itemTitle)); - } - - public SubMenu addSubMenuItem() { - itemAdded = true; - SubMenu subMenu = menu.addSubMenu(groupId, itemId, itemCategoryOrder, itemTitle); - setItem(subMenu.getItem()); - return subMenu; - } - - public boolean hasAddedItem() { - return itemAdded; - } - - @SuppressWarnings("unchecked") - private T newInstance(String className, Class[] constructorSignature, - Object[] arguments) { - try { - Class clazz = mContext.getClassLoader().loadClass(className); - Constructor constructor = clazz.getConstructor(constructorSignature); - return (T) constructor.newInstance(arguments); - } catch (Exception e) { - Log.w(LOG_TAG, "Cannot instantiate class: " + className, e); - } - return null; - } - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/view/MenuItem.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/view/MenuItem.java deleted file mode 100644 index 7fc3aa430..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/view/MenuItem.java +++ /dev/null @@ -1,598 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.view; - -import android.content.Intent; -import android.graphics.drawable.Drawable; -import android.view.ContextMenu.ContextMenuInfo; -import android.view.View; - -/** - * Interface for direct access to a previously created menu item. - *

- * An Item is returned by calling one of the {@link android.view.Menu#add} - * methods. - *

- * For a feature set of specific menu types, see {@link Menu}. - * - *

- *

Developer Guides

- *

For information about creating menus, read the - * Menus developer guide.

- *
- */ -public interface MenuItem { - /* - * These should be kept in sync with attrs.xml enum constants for showAsAction - */ - /** Never show this item as a button in an Action Bar. */ - public static final int SHOW_AS_ACTION_NEVER = android.view.MenuItem.SHOW_AS_ACTION_NEVER; - /** Show this item as a button in an Action Bar if the system decides there is room for it. */ - public static final int SHOW_AS_ACTION_IF_ROOM = android.view.MenuItem.SHOW_AS_ACTION_IF_ROOM; - /** - * Always show this item as a button in an Action Bar. - * Use sparingly! If too many items are set to always show in the Action Bar it can - * crowd the Action Bar and degrade the user experience on devices with smaller screens. - * A good rule of thumb is to have no more than 2 items set to always show at a time. - */ - public static final int SHOW_AS_ACTION_ALWAYS = android.view.MenuItem.SHOW_AS_ACTION_ALWAYS; - - /** - * When this item is in the action bar, always show it with a text label even if - * it also has an icon specified. - */ - public static final int SHOW_AS_ACTION_WITH_TEXT = android.view.MenuItem.SHOW_AS_ACTION_WITH_TEXT; - - /** - * This item's action view collapses to a normal menu item. - * When expanded, the action view temporarily takes over - * a larger segment of its container. - */ - public static final int SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW = android.view.MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW; - - /** - * Interface definition for a callback to be invoked when a menu item is - * clicked. - * - * @see Activity#onContextItemSelected(MenuItem) - * @see Activity#onOptionsItemSelected(MenuItem) - */ - public interface OnMenuItemClickListener { - /** - * Called when a menu item has been invoked. This is the first code - * that is executed; if it returns true, no other callbacks will be - * executed. - * - * @param item The menu item that was invoked. - * - * @return Return true to consume this click and prevent others from - * executing. - */ - public boolean onMenuItemClick(MenuItem item); - } - - /** - * Interface definition for a callback to be invoked when a menu item - * marked with {@link MenuItem#SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW} is - * expanded or collapsed. - * - * @see MenuItem#expandActionView() - * @see MenuItem#collapseActionView() - * @see MenuItem#setShowAsActionFlags(int) - */ - public interface OnActionExpandListener { - /** - * Called when a menu item with {@link MenuItem#SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW} - * is expanded. - * @param item Item that was expanded - * @return true if the item should expand, false if expansion should be suppressed. - */ - public boolean onMenuItemActionExpand(MenuItem item); - - /** - * Called when a menu item with {@link MenuItem#SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW} - * is collapsed. - * @param item Item that was collapsed - * @return true if the item should collapse, false if collapsing should be suppressed. - */ - public boolean onMenuItemActionCollapse(MenuItem item); - } - - /** - * Return the identifier for this menu item. The identifier can not - * be changed after the menu is created. - * - * @return The menu item's identifier. - */ - public int getItemId(); - - /** - * Return the group identifier that this menu item is part of. The group - * identifier can not be changed after the menu is created. - * - * @return The menu item's group identifier. - */ - public int getGroupId(); - - /** - * Return the category and order within the category of this item. This - * item will be shown before all items (within its category) that have - * order greater than this value. - *

- * An order integer contains the item's category (the upper bits of the - * integer; set by or/add the category with the order within the - * category) and the ordering of the item within that category (the - * lower bits). Example categories are {@link Menu#CATEGORY_SYSTEM}, - * {@link Menu#CATEGORY_SECONDARY}, {@link Menu#CATEGORY_ALTERNATIVE}, - * {@link Menu#CATEGORY_CONTAINER}. See {@link Menu} for a full list. - * - * @return The order of this item. - */ - public int getOrder(); - - /** - * Change the title associated with this item. - * - * @param title The new text to be displayed. - * @return This Item so additional setters can be called. - */ - public MenuItem setTitle(CharSequence title); - - /** - * Change the title associated with this item. - *

- * Some menu types do not sufficient space to show the full title, and - * instead a condensed title is preferred. See {@link Menu} for more - * information. - * - * @param title The resource id of the new text to be displayed. - * @return This Item so additional setters can be called. - * @see #setTitleCondensed(CharSequence) - */ - - public MenuItem setTitle(int title); - - /** - * Retrieve the current title of the item. - * - * @return The title. - */ - public CharSequence getTitle(); - - /** - * Change the condensed title associated with this item. The condensed - * title is used in situations where the normal title may be too long to - * be displayed. - * - * @param title The new text to be displayed as the condensed title. - * @return This Item so additional setters can be called. - */ - public MenuItem setTitleCondensed(CharSequence title); - - /** - * Retrieve the current condensed title of the item. If a condensed - * title was never set, it will return the normal title. - * - * @return The condensed title, if it exists. - * Otherwise the normal title. - */ - public CharSequence getTitleCondensed(); - - /** - * Change the icon associated with this item. This icon will not always be - * shown, so the title should be sufficient in describing this item. See - * {@link Menu} for the menu types that support icons. - * - * @param icon The new icon (as a Drawable) to be displayed. - * @return This Item so additional setters can be called. - */ - public MenuItem setIcon(Drawable icon); - - /** - * Change the icon associated with this item. This icon will not always be - * shown, so the title should be sufficient in describing this item. See - * {@link Menu} for the menu types that support icons. - *

- * This method will set the resource ID of the icon which will be used to - * lazily get the Drawable when this item is being shown. - * - * @param iconRes The new icon (as a resource ID) to be displayed. - * @return This Item so additional setters can be called. - */ - public MenuItem setIcon(int iconRes); - - /** - * Returns the icon for this item as a Drawable (getting it from resources if it hasn't been - * loaded before). - * - * @return The icon as a Drawable. - */ - public Drawable getIcon(); - - /** - * Change the Intent associated with this item. By default there is no - * Intent associated with a menu item. If you set one, and nothing - * else handles the item, then the default behavior will be to call - * {@link android.content.Context#startActivity} with the given Intent. - * - *

Note that setIntent() can not be used with the versions of - * {@link Menu#add} that take a Runnable, because {@link Runnable#run} - * does not return a value so there is no way to tell if it handled the - * item. In this case it is assumed that the Runnable always handles - * the item, and the intent will never be started. - * - * @see #getIntent - * @param intent The Intent to associated with the item. This Intent - * object is not copied, so be careful not to - * modify it later. - * @return This Item so additional setters can be called. - */ - public MenuItem setIntent(Intent intent); - - /** - * Return the Intent associated with this item. This returns a - * reference to the Intent which you can change as desired to modify - * what the Item is holding. - * - * @see #setIntent - * @return Returns the last value supplied to {@link #setIntent}, or - * null. - */ - public Intent getIntent(); - - /** - * Change both the numeric and alphabetic shortcut associated with this - * item. Note that the shortcut will be triggered when the key that - * generates the given character is pressed alone or along with with the alt - * key. Also note that case is not significant and that alphabetic shortcut - * characters will be displayed in lower case. - *

- * See {@link Menu} for the menu types that support shortcuts. - * - * @param numericChar The numeric shortcut key. This is the shortcut when - * using a numeric (e.g., 12-key) keyboard. - * @param alphaChar The alphabetic shortcut key. This is the shortcut when - * using a keyboard with alphabetic keys. - * @return This Item so additional setters can be called. - */ - public MenuItem setShortcut(char numericChar, char alphaChar); - - /** - * Change the numeric shortcut associated with this item. - *

- * See {@link Menu} for the menu types that support shortcuts. - * - * @param numericChar The numeric shortcut key. This is the shortcut when - * using a 12-key (numeric) keyboard. - * @return This Item so additional setters can be called. - */ - public MenuItem setNumericShortcut(char numericChar); - - /** - * Return the char for this menu item's numeric (12-key) shortcut. - * - * @return Numeric character to use as a shortcut. - */ - public char getNumericShortcut(); - - /** - * Change the alphabetic shortcut associated with this item. The shortcut - * will be triggered when the key that generates the given character is - * pressed alone or along with with the alt key. Case is not significant and - * shortcut characters will be displayed in lower case. Note that menu items - * with the characters '\b' or '\n' as shortcuts will get triggered by the - * Delete key or Carriage Return key, respectively. - *

- * See {@link Menu} for the menu types that support shortcuts. - * - * @param alphaChar The alphabetic shortcut key. This is the shortcut when - * using a keyboard with alphabetic keys. - * @return This Item so additional setters can be called. - */ - public MenuItem setAlphabeticShortcut(char alphaChar); - - /** - * Return the char for this menu item's alphabetic shortcut. - * - * @return Alphabetic character to use as a shortcut. - */ - public char getAlphabeticShortcut(); - - /** - * Control whether this item can display a check mark. Setting this does - * not actually display a check mark (see {@link #setChecked} for that); - * rather, it ensures there is room in the item in which to display a - * check mark. - *

- * See {@link Menu} for the menu types that support check marks. - * - * @param checkable Set to true to allow a check mark, false to - * disallow. The default is false. - * @see #setChecked - * @see #isCheckable - * @see Menu#setGroupCheckable - * @return This Item so additional setters can be called. - */ - public MenuItem setCheckable(boolean checkable); - - /** - * Return whether the item can currently display a check mark. - * - * @return If a check mark can be displayed, returns true. - * - * @see #setCheckable - */ - public boolean isCheckable(); - - /** - * Control whether this item is shown with a check mark. Note that you - * must first have enabled checking with {@link #setCheckable} or else - * the check mark will not appear. If this item is a member of a group that contains - * mutually-exclusive items (set via {@link Menu#setGroupCheckable(int, boolean, boolean)}, - * the other items in the group will be unchecked. - *

- * See {@link Menu} for the menu types that support check marks. - * - * @see #setCheckable - * @see #isChecked - * @see Menu#setGroupCheckable - * @param checked Set to true to display a check mark, false to hide - * it. The default value is false. - * @return This Item so additional setters can be called. - */ - public MenuItem setChecked(boolean checked); - - /** - * Return whether the item is currently displaying a check mark. - * - * @return If a check mark is displayed, returns true. - * - * @see #setChecked - */ - public boolean isChecked(); - - /** - * Sets the visibility of the menu item. Even if a menu item is not visible, - * it may still be invoked via its shortcut (to completely disable an item, - * set it to invisible and {@link #setEnabled(boolean) disabled}). - * - * @param visible If true then the item will be visible; if false it is - * hidden. - * @return This Item so additional setters can be called. - */ - public MenuItem setVisible(boolean visible); - - /** - * Return the visibility of the menu item. - * - * @return If true the item is visible; else it is hidden. - */ - public boolean isVisible(); - - /** - * Sets whether the menu item is enabled. Disabling a menu item will not - * allow it to be invoked via its shortcut. The menu item will still be - * visible. - * - * @param enabled If true then the item will be invokable; if false it is - * won't be invokable. - * @return This Item so additional setters can be called. - */ - public MenuItem setEnabled(boolean enabled); - - /** - * Return the enabled state of the menu item. - * - * @return If true the item is enabled and hence invokable; else it is not. - */ - public boolean isEnabled(); - - /** - * Check whether this item has an associated sub-menu. I.e. it is a - * sub-menu of another menu. - * - * @return If true this item has a menu; else it is a - * normal item. - */ - public boolean hasSubMenu(); - - /** - * Get the sub-menu to be invoked when this item is selected, if it has - * one. See {@link #hasSubMenu()}. - * - * @return The associated menu if there is one, else null - */ - public SubMenu getSubMenu(); - - /** - * Set a custom listener for invocation of this menu item. In most - * situations, it is more efficient and easier to use - * {@link Activity#onOptionsItemSelected(MenuItem)} or - * {@link Activity#onContextItemSelected(MenuItem)}. - * - * @param menuItemClickListener The object to receive invokations. - * @return This Item so additional setters can be called. - * @see Activity#onOptionsItemSelected(MenuItem) - * @see Activity#onContextItemSelected(MenuItem) - */ - public MenuItem setOnMenuItemClickListener(MenuItem.OnMenuItemClickListener menuItemClickListener); - - /** - * Gets the extra information linked to this menu item. This extra - * information is set by the View that added this menu item to the - * menu. - * - * @see OnCreateContextMenuListener - * @return The extra information linked to the View that added this - * menu item to the menu. This can be null. - */ - public ContextMenuInfo getMenuInfo(); - - /** - * Sets how this item should display in the presence of an Action Bar. - * The parameter actionEnum is a flag set. One of {@link #SHOW_AS_ACTION_ALWAYS}, - * {@link #SHOW_AS_ACTION_IF_ROOM}, or {@link #SHOW_AS_ACTION_NEVER} should - * be used, and you may optionally OR the value with {@link #SHOW_AS_ACTION_WITH_TEXT}. - * SHOW_AS_ACTION_WITH_TEXT requests that when the item is shown as an action, - * it should be shown with a text label. - * - * @param actionEnum How the item should display. One of - * {@link #SHOW_AS_ACTION_ALWAYS}, {@link #SHOW_AS_ACTION_IF_ROOM}, or - * {@link #SHOW_AS_ACTION_NEVER}. SHOW_AS_ACTION_NEVER is the default. - * - * @see android.app.ActionBar - * @see #setActionView(View) - */ - public void setShowAsAction(int actionEnum); - - /** - * Sets how this item should display in the presence of an Action Bar. - * The parameter actionEnum is a flag set. One of {@link #SHOW_AS_ACTION_ALWAYS}, - * {@link #SHOW_AS_ACTION_IF_ROOM}, or {@link #SHOW_AS_ACTION_NEVER} should - * be used, and you may optionally OR the value with {@link #SHOW_AS_ACTION_WITH_TEXT}. - * SHOW_AS_ACTION_WITH_TEXT requests that when the item is shown as an action, - * it should be shown with a text label. - * - *

Note: This method differs from {@link #setShowAsAction(int)} only in that it - * returns the current MenuItem instance for call chaining. - * - * @param actionEnum How the item should display. One of - * {@link #SHOW_AS_ACTION_ALWAYS}, {@link #SHOW_AS_ACTION_IF_ROOM}, or - * {@link #SHOW_AS_ACTION_NEVER}. SHOW_AS_ACTION_NEVER is the default. - * - * @see android.app.ActionBar - * @see #setActionView(View) - * @return This MenuItem instance for call chaining. - */ - public MenuItem setShowAsActionFlags(int actionEnum); - - /** - * Set an action view for this menu item. An action view will be displayed in place - * of an automatically generated menu item element in the UI when this item is shown - * as an action within a parent. - *

- * Note: Setting an action view overrides the action provider - * set via {@link #setActionProvider(ActionProvider)}. - *

- * - * @param view View to use for presenting this item to the user. - * @return This Item so additional setters can be called. - * - * @see #setShowAsAction(int) - */ - public MenuItem setActionView(View view); - - /** - * Set an action view for this menu item. An action view will be displayed in place - * of an automatically generated menu item element in the UI when this item is shown - * as an action within a parent. - *

- * Note: Setting an action view overrides the action provider - * set via {@link #setActionProvider(ActionProvider)}. - *

- * - * @param resId Layout resource to use for presenting this item to the user. - * @return This Item so additional setters can be called. - * - * @see #setShowAsAction(int) - */ - public MenuItem setActionView(int resId); - - /** - * Returns the currently set action view for this menu item. - * - * @return This item's action view - * - * @see #setActionView(View) - * @see #setShowAsAction(int) - */ - public View getActionView(); - - /** - * Sets the {@link ActionProvider} responsible for creating an action view if - * the item is placed on the action bar. The provider also provides a default - * action invoked if the item is placed in the overflow menu. - *

- * Note: Setting an action provider overrides the action view - * set via {@link #setActionView(int)} or {@link #setActionView(View)}. - *

- * - * @param actionProvider The action provider. - * @return This Item so additional setters can be called. - * - * @see ActionProvider - */ - public MenuItem setActionProvider(ActionProvider actionProvider); - - /** - * Gets the {@link ActionProvider}. - * - * @return The action provider. - * - * @see ActionProvider - * @see #setActionProvider(ActionProvider) - */ - public ActionProvider getActionProvider(); - - /** - * Expand the action view associated with this menu item. - * The menu item must have an action view set, as well as - * the showAsAction flag {@link #SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW}. - * If a listener has been set using {@link #setOnActionExpandListener(OnActionExpandListener)} - * it will have its {@link OnActionExpandListener#onMenuItemActionExpand(MenuItem)} - * method invoked. The listener may return false from this method to prevent expanding - * the action view. - * - * @return true if the action view was expanded, false otherwise. - */ - public boolean expandActionView(); - - /** - * Collapse the action view associated with this menu item. - * The menu item must have an action view set, as well as the showAsAction flag - * {@link #SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW}. If a listener has been set using - * {@link #setOnActionExpandListener(OnActionExpandListener)} it will have its - * {@link OnActionExpandListener#onMenuItemActionCollapse(MenuItem)} method invoked. - * The listener may return false from this method to prevent collapsing the action view. - * - * @return true if the action view was collapsed, false otherwise. - */ - public boolean collapseActionView(); - - /** - * Returns true if this menu item's action view has been expanded. - * - * @return true if the item's action view is expanded, false otherwise. - * - * @see #expandActionView() - * @see #collapseActionView() - * @see #SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW - * @see OnActionExpandListener - */ - public boolean isActionViewExpanded(); - - /** - * Set an {@link OnActionExpandListener} on this menu item to be notified when - * the associated action view is expanded or collapsed. The menu item must - * be configured to expand or collapse its action view using the flag - * {@link #SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW}. - * - * @param listener Listener that will respond to expand/collapse events - * @return This menu item instance for call chaining - */ - public MenuItem setOnActionExpandListener(OnActionExpandListener listener); -} \ No newline at end of file diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/view/SubMenu.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/view/SubMenu.java deleted file mode 100644 index 397fd1c2d..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/view/SubMenu.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.view; - -import android.graphics.drawable.Drawable; -import android.view.View; - -/** - * Subclass of {@link Menu} for sub menus. - *

- * Sub menus do not support item icons, or nested sub menus. - * - *

- *

Developer Guides

- *

For information about creating menus, read the - * Menus developer guide.

- *
- */ - -public interface SubMenu extends Menu { - /** - * Sets the submenu header's title to the title given in titleRes - * resource identifier. - * - * @param titleRes The string resource identifier used for the title. - * @return This SubMenu so additional setters can be called. - */ - public SubMenu setHeaderTitle(int titleRes); - - /** - * Sets the submenu header's title to the title given in title. - * - * @param title The character sequence used for the title. - * @return This SubMenu so additional setters can be called. - */ - public SubMenu setHeaderTitle(CharSequence title); - - /** - * Sets the submenu header's icon to the icon given in iconRes - * resource id. - * - * @param iconRes The resource identifier used for the icon. - * @return This SubMenu so additional setters can be called. - */ - public SubMenu setHeaderIcon(int iconRes); - - /** - * Sets the submenu header's icon to the icon given in icon - * {@link Drawable}. - * - * @param icon The {@link Drawable} used for the icon. - * @return This SubMenu so additional setters can be called. - */ - public SubMenu setHeaderIcon(Drawable icon); - - /** - * Sets the header of the submenu to the {@link View} given in - * view. This replaces the header title and icon (and those - * replace this). - * - * @param view The {@link View} used for the header. - * @return This SubMenu so additional setters can be called. - */ - public SubMenu setHeaderView(View view); - - /** - * Clears the header of the submenu. - */ - public void clearHeader(); - - /** - * Change the icon associated with this submenu's item in its parent menu. - * - * @see MenuItem#setIcon(int) - * @param iconRes The new icon (as a resource ID) to be displayed. - * @return This SubMenu so additional setters can be called. - */ - public SubMenu setIcon(int iconRes); - - /** - * Change the icon associated with this submenu's item in its parent menu. - * - * @see MenuItem#setIcon(Drawable) - * @param icon The new icon (as a Drawable) to be displayed. - * @return This SubMenu so additional setters can be called. - */ - public SubMenu setIcon(Drawable icon); - - /** - * Gets the {@link MenuItem} that represents this submenu in the parent - * menu. Use this for setting additional item attributes. - * - * @return The {@link MenuItem} that launches the submenu when invoked. - */ - public MenuItem getItem(); -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/view/Window.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/view/Window.java deleted file mode 100644 index a340a4291..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/view/Window.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * Copyright (C) 2011 Jake Wharton - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.view; - -import android.content.Context; - -/** - *

Abstract base class for a top-level window look and behavior policy. An - * instance of this class should be used as the top-level view added to the - * window manager. It provides standard UI policies such as a background, title - * area, default key processing, etc.

- * - *

The only existing implementation of this abstract class is - * android.policy.PhoneWindow, which you should instantiate when needing a - * Window. Eventually that class will be refactored and a factory method added - * for creating Window instances without knowing about a particular - * implementation.

- */ -public abstract class Window extends android.view.Window { - public static final long FEATURE_ACTION_BAR = android.view.Window.FEATURE_ACTION_BAR; - public static final long FEATURE_ACTION_BAR_OVERLAY = android.view.Window.FEATURE_ACTION_BAR_OVERLAY; - public static final long FEATURE_ACTION_MODE_OVERLAY = android.view.Window.FEATURE_ACTION_MODE_OVERLAY; - public static final long FEATURE_NO_TITLE = android.view.Window.FEATURE_NO_TITLE; - public static final long FEATURE_PROGRESS = android.view.Window.FEATURE_PROGRESS; - public static final long FEATURE_INDETERMINATE_PROGRESS = android.view.Window.FEATURE_INDETERMINATE_PROGRESS; - - /** - * Create a new instance for a context. - * - * @param context Context. - */ - private Window(Context context) { - super(context); - } - - - public interface Callback { - /** - * Called when a panel's menu item has been selected by the user. - * - * @param featureId The panel that the menu is in. - * @param item The menu item that was selected. - * - * @return boolean Return true to finish processing of selection, or - * false to perform the normal menu handling (calling its - * Runnable or sending a Message to its target Handler). - */ - public boolean onMenuItemSelected(int featureId, MenuItem item); - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/widget/ActivityChooserModel.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/widget/ActivityChooserModel.java deleted file mode 100644 index 379207471..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/widget/ActivityChooserModel.java +++ /dev/null @@ -1,1131 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.widget; - -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.pm.ResolveInfo; -import android.database.DataSetObservable; -import android.os.Handler; -import android.text.TextUtils; -import android.util.Log; -import android.util.Xml; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; -import org.xmlpull.v1.XmlSerializer; - -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.LinkedHashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.Executor; - -/** - *

- * This class represents a data model for choosing a component for handing a - * given {@link Intent}. The model is responsible for querying the system for - * activities that can handle the given intent and order found activities - * based on historical data of previous choices. The historical data is stored - * in an application private file. If a client does not want to have persistent - * choice history the file can be omitted, thus the activities will be ordered - * based on historical usage for the current session. - *

- *

- * For each backing history file there is a singleton instance of this class. Thus, - * several clients that specify the same history file will share the same model. Note - * that if multiple clients are sharing the same model they should implement semantically - * equivalent functionality since setting the model intent will change the found - * activities and they may be inconsistent with the functionality of some of the clients. - * For example, choosing a share activity can be implemented by a single backing - * model and two different views for performing the selection. If however, one of the - * views is used for sharing but the other for importing, for example, then each - * view should be backed by a separate model. - *

- *

- * The way clients interact with this class is as follows: - *

- *

- *

- * 
- *  // Get a model and set it to a couple of clients with semantically similar function.
- *  ActivityChooserModel dataModel =
- *      ActivityChooserModel.get(context, "task_specific_history_file_name.xml");
- *
- *  ActivityChooserModelClient modelClient1 = getActivityChooserModelClient1();
- *  modelClient1.setActivityChooserModel(dataModel);
- *
- *  ActivityChooserModelClient modelClient2 = getActivityChooserModelClient2();
- *  modelClient2.setActivityChooserModel(dataModel);
- *
- *  // Set an intent to choose a an activity for.
- *  dataModel.setIntent(intent);
- * 
- * 
- * 

- *

- * Note: This class is thread safe. - *

- * - * @hide - */ -class ActivityChooserModel extends DataSetObservable { - - /** - * Client that utilizes an {@link ActivityChooserModel}. - */ - public interface ActivityChooserModelClient { - - /** - * Sets the {@link ActivityChooserModel}. - * - * @param dataModel The model. - */ - public void setActivityChooserModel(ActivityChooserModel dataModel); - } - - /** - * Defines a sorter that is responsible for sorting the activities - * based on the provided historical choices and an intent. - */ - public interface ActivitySorter { - - /** - * Sorts the activities in descending order of relevance - * based on previous history and an intent. - * - * @param intent The {@link Intent}. - * @param activities Activities to be sorted. - * @param historicalRecords Historical records. - */ - // This cannot be done by a simple comparator since an Activity weight - // is computed from history. Note that Activity implements Comparable. - public void sort(Intent intent, List activities, - List historicalRecords); - } - - /** - * Listener for choosing an activity. - */ - public interface OnChooseActivityListener { - - /** - * Called when an activity has been chosen. The client can decide whether - * an activity can be chosen and if so the caller of - * {@link ActivityChooserModel#chooseActivity(int)} will receive and {@link Intent} - * for launching it. - *

- * Note: Modifying the intent is not permitted and - * any changes to the latter will be ignored. - *

- * - * @param host The listener's host model. - * @param intent The intent for launching the chosen activity. - * @return Whether the intent is handled and should not be delivered to clients. - * - * @see ActivityChooserModel#chooseActivity(int) - */ - public boolean onChooseActivity(ActivityChooserModel host, Intent intent); - } - - /** - * Flag for selecting debug mode. - */ - private static final boolean DEBUG = false; - - /** - * Tag used for logging. - */ - private static final String LOG_TAG = ActivityChooserModel.class.getSimpleName(); - - /** - * The root tag in the history file. - */ - private static final String TAG_HISTORICAL_RECORDS = "historical-records"; - - /** - * The tag for a record in the history file. - */ - private static final String TAG_HISTORICAL_RECORD = "historical-record"; - - /** - * Attribute for the activity. - */ - private static final String ATTRIBUTE_ACTIVITY = "activity"; - - /** - * Attribute for the choice time. - */ - private static final String ATTRIBUTE_TIME = "time"; - - /** - * Attribute for the choice weight. - */ - private static final String ATTRIBUTE_WEIGHT = "weight"; - - /** - * The default name of the choice history file. - */ - public static final String DEFAULT_HISTORY_FILE_NAME = - "activity_choser_model_history.xml"; - - /** - * The default maximal length of the choice history. - */ - public static final int DEFAULT_HISTORY_MAX_LENGTH = 50; - - /** - * The amount with which to inflate a chosen activity when set as default. - */ - private static final int DEFAULT_ACTIVITY_INFLATION = 5; - - /** - * Default weight for a choice record. - */ - private static final float DEFAULT_HISTORICAL_RECORD_WEIGHT = 1.0f; - - /** - * The extension of the history file. - */ - private static final String HISTORY_FILE_EXTENSION = ".xml"; - - /** - * An invalid item index. - */ - private static final int INVALID_INDEX = -1; - - /** - * Lock to guard the model registry. - */ - private static final Object sRegistryLock = new Object(); - - /** - * This the registry for data models. - */ - private static final Map sDataModelRegistry = - new HashMap(); - - /** - * Lock for synchronizing on this instance. - */ - private final Object mInstanceLock = new Object(); - - /** - * List of activities that can handle the current intent. - */ - private final List mActivites = new ArrayList(); - - /** - * List with historical choice records. - */ - private final List mHistoricalRecords = new ArrayList(); - - /** - * Context for accessing resources. - */ - private final Context mContext; - - /** - * The name of the history file that backs this model. - */ - private final String mHistoryFileName; - - /** - * The intent for which a activity is being chosen. - */ - private Intent mIntent; - - /** - * The sorter for ordering activities based on intent and past choices. - */ - private ActivitySorter mActivitySorter = new DefaultSorter(); - - /** - * The maximal length of the choice history. - */ - private int mHistoryMaxSize = DEFAULT_HISTORY_MAX_LENGTH; - - /** - * Flag whether choice history can be read. In general many clients can - * share the same data model and {@link #readHistoricalData()} may be called - * by arbitrary of them any number of times. Therefore, this class guarantees - * that the very first read succeeds and subsequent reads can be performed - * only after a call to {@link #persistHistoricalData()} followed by change - * of the share records. - */ - private boolean mCanReadHistoricalData = true; - - /** - * Flag whether the choice history was read. This is used to enforce that - * before calling {@link #persistHistoricalData()} a call to - * {@link #persistHistoricalData()} has been made. This aims to avoid a - * scenario in which a choice history file exits, it is not read yet and - * it is overwritten. Note that always all historical records are read in - * full and the file is rewritten. This is necessary since we need to - * purge old records that are outside of the sliding window of past choices. - */ - private boolean mReadShareHistoryCalled = false; - - /** - * Flag whether the choice records have changed. In general many clients can - * share the same data model and {@link #persistHistoricalData()} may be called - * by arbitrary of them any number of times. Therefore, this class guarantees - * that choice history will be persisted only if it has changed. - */ - private boolean mHistoricalRecordsChanged = true; - - /** - * Hander for scheduling work on client tread. - */ - private final Handler mHandler = new Handler(); - - /** - * Policy for controlling how the model handles chosen activities. - */ - private OnChooseActivityListener mActivityChoserModelPolicy; - - /** - * Gets the data model backed by the contents of the provided file with historical data. - * Note that only one data model is backed by a given file, thus multiple calls with - * the same file name will return the same model instance. If no such instance is present - * it is created. - *

- * Note: To use the default historical data file clients should explicitly - * pass as file name {@link #DEFAULT_HISTORY_FILE_NAME}. If no persistence of the choice - * history is desired clients should pass null for the file name. In such - * case a new model is returned for each invocation. - *

- * - *

- * Always use difference historical data files for semantically different actions. - * For example, sharing is different from importing. - *

- * - * @param context Context for loading resources. - * @param historyFileName File name with choice history, null - * if the model should not be backed by a file. In this case the activities - * will be ordered only by data from the current session. - * - * @return The model. - */ - public static ActivityChooserModel get(Context context, String historyFileName) { - synchronized (sRegistryLock) { - ActivityChooserModel dataModel = sDataModelRegistry.get(historyFileName); - if (dataModel == null) { - dataModel = new ActivityChooserModel(context, historyFileName); - sDataModelRegistry.put(historyFileName, dataModel); - } - dataModel.readHistoricalData(); - return dataModel; - } - } - - /** - * Creates a new instance. - * - * @param context Context for loading resources. - * @param historyFileName The history XML file. - */ - private ActivityChooserModel(Context context, String historyFileName) { - mContext = context.getApplicationContext(); - if (!TextUtils.isEmpty(historyFileName) - && !historyFileName.endsWith(HISTORY_FILE_EXTENSION)) { - mHistoryFileName = historyFileName + HISTORY_FILE_EXTENSION; - } else { - mHistoryFileName = historyFileName; - } - } - - /** - * Sets an intent for which to choose a activity. - *

- * Note: Clients must set only semantically similar - * intents for each data model. - *

- * - * @param intent The intent. - */ - public void setIntent(Intent intent) { - synchronized (mInstanceLock) { - if (mIntent == intent) { - return; - } - mIntent = intent; - loadActivitiesLocked(); - } - } - - /** - * Gets the intent for which a activity is being chosen. - * - * @return The intent. - */ - public Intent getIntent() { - synchronized (mInstanceLock) { - return mIntent; - } - } - - /** - * Gets the number of activities that can handle the intent. - * - * @return The activity count. - * - * @see #setIntent(Intent) - */ - public int getActivityCount() { - synchronized (mInstanceLock) { - return mActivites.size(); - } - } - - /** - * Gets an activity at a given index. - * - * @return The activity. - * - * @see ActivityResolveInfo - * @see #setIntent(Intent) - */ - public ResolveInfo getActivity(int index) { - synchronized (mInstanceLock) { - return mActivites.get(index).resolveInfo; - } - } - - /** - * Gets the index of a the given activity. - * - * @param activity The activity index. - * - * @return The index if found, -1 otherwise. - */ - public int getActivityIndex(ResolveInfo activity) { - List activities = mActivites; - final int activityCount = activities.size(); - for (int i = 0; i < activityCount; i++) { - ActivityResolveInfo currentActivity = activities.get(i); - if (currentActivity.resolveInfo == activity) { - return i; - } - } - return INVALID_INDEX; - } - - /** - * Chooses a activity to handle the current intent. This will result in - * adding a historical record for that action and construct intent with - * its component name set such that it can be immediately started by the - * client. - *

- * Note: By calling this method the client guarantees - * that the returned intent will be started. This intent is returned to - * the client solely to let additional customization before the start. - *

- * - * @return An {@link Intent} for launching the activity or null if the - * policy has consumed the intent. - * - * @see HistoricalRecord - * @see OnChooseActivityListener - */ - public Intent chooseActivity(int index) { - ActivityResolveInfo chosenActivity = mActivites.get(index); - - ComponentName chosenName = new ComponentName( - chosenActivity.resolveInfo.activityInfo.packageName, - chosenActivity.resolveInfo.activityInfo.name); - - Intent choiceIntent = new Intent(mIntent); - choiceIntent.setComponent(chosenName); - - if (mActivityChoserModelPolicy != null) { - // Do not allow the policy to change the intent. - Intent choiceIntentCopy = new Intent(choiceIntent); - final boolean handled = mActivityChoserModelPolicy.onChooseActivity(this, - choiceIntentCopy); - if (handled) { - return null; - } - } - - HistoricalRecord historicalRecord = new HistoricalRecord(chosenName, - System.currentTimeMillis(), DEFAULT_HISTORICAL_RECORD_WEIGHT); - addHisoricalRecord(historicalRecord); - - return choiceIntent; - } - - /** - * Sets the listener for choosing an activity. - * - * @param listener The listener. - */ - public void setOnChooseActivityListener(OnChooseActivityListener listener) { - mActivityChoserModelPolicy = listener; - } - - /** - * Gets the default activity, The default activity is defined as the one - * with highest rank i.e. the first one in the list of activities that can - * handle the intent. - * - * @return The default activity, null id not activities. - * - * @see #getActivity(int) - */ - public ResolveInfo getDefaultActivity() { - synchronized (mInstanceLock) { - if (!mActivites.isEmpty()) { - return mActivites.get(0).resolveInfo; - } - } - return null; - } - - /** - * Sets the default activity. The default activity is set by adding a - * historical record with weight high enough that this activity will - * become the highest ranked. Such a strategy guarantees that the default - * will eventually change if not used. Also the weight of the record for - * setting a default is inflated with a constant amount to guarantee that - * it will stay as default for awhile. - * - * @param index The index of the activity to set as default. - */ - public void setDefaultActivity(int index) { - ActivityResolveInfo newDefaultActivity = mActivites.get(index); - ActivityResolveInfo oldDefaultActivity = mActivites.get(0); - - final float weight; - if (oldDefaultActivity != null) { - // Add a record with weight enough to boost the chosen at the top. - weight = oldDefaultActivity.weight - newDefaultActivity.weight - + DEFAULT_ACTIVITY_INFLATION; - } else { - weight = DEFAULT_HISTORICAL_RECORD_WEIGHT; - } - - ComponentName defaultName = new ComponentName( - newDefaultActivity.resolveInfo.activityInfo.packageName, - newDefaultActivity.resolveInfo.activityInfo.name); - HistoricalRecord historicalRecord = new HistoricalRecord(defaultName, - System.currentTimeMillis(), weight); - addHisoricalRecord(historicalRecord); - } - - /** - * Reads the history data from the backing file if the latter - * was provided. Calling this method more than once before a call - * to {@link #persistHistoricalData()} has been made has no effect. - *

- * Note: Historical data is read asynchronously and - * as soon as the reading is completed any registered - * {@link DataSetObserver}s will be notified. Also no historical - * data is read until this method is invoked. - *

- */ - private void readHistoricalData() { - synchronized (mInstanceLock) { - if (!mCanReadHistoricalData || !mHistoricalRecordsChanged) { - return; - } - mCanReadHistoricalData = false; - mReadShareHistoryCalled = true; - if (!TextUtils.isEmpty(mHistoryFileName)) { - /*AsyncTask.*/SERIAL_EXECUTOR.execute(new HistoryLoader()); - } - } - } - - private static final SerialExecutor SERIAL_EXECUTOR = new SerialExecutor(); - - private static class SerialExecutor implements Executor { - final LinkedList mTasks = new LinkedList(); - Runnable mActive; - - public synchronized void execute(final Runnable r) { - mTasks.offer(new Runnable() { - public void run() { - try { - r.run(); - } finally { - scheduleNext(); - } - } - }); - if (mActive == null) { - scheduleNext(); - } - } - - protected synchronized void scheduleNext() { - if ((mActive = mTasks.poll()) != null) { - mActive.run(); - } - } - } - - /** - * Persists the history data to the backing file if the latter - * was provided. Calling this method before a call to {@link #readHistoricalData()} - * throws an exception. Calling this method more than one without choosing an - * activity has not effect. - * - * @throws IllegalStateException If this method is called before a call to - * {@link #readHistoricalData()}. - */ - private void persistHistoricalData() { - synchronized (mInstanceLock) { - if (!mReadShareHistoryCalled) { - throw new IllegalStateException("No preceding call to #readHistoricalData"); - } - if (!mHistoricalRecordsChanged) { - return; - } - mHistoricalRecordsChanged = false; - mCanReadHistoricalData = true; - if (!TextUtils.isEmpty(mHistoryFileName)) { - /*AsyncTask.*/SERIAL_EXECUTOR.execute(new HistoryPersister()); - } - } - } - - /** - * Sets the sorter for ordering activities based on historical data and an intent. - * - * @param activitySorter The sorter. - * - * @see ActivitySorter - */ - public void setActivitySorter(ActivitySorter activitySorter) { - synchronized (mInstanceLock) { - if (mActivitySorter == activitySorter) { - return; - } - mActivitySorter = activitySorter; - sortActivities(); - } - } - - /** - * Sorts the activities based on history and an intent. If - * a sorter is not specified this a default implementation is used. - * - * @see #setActivitySorter(ActivitySorter) - */ - private void sortActivities() { - synchronized (mInstanceLock) { - if (mActivitySorter != null && !mActivites.isEmpty()) { - mActivitySorter.sort(mIntent, mActivites, - Collections.unmodifiableList(mHistoricalRecords)); - notifyChanged(); - } - } - } - - /** - * Sets the maximal size of the historical data. Defaults to - * {@link #DEFAULT_HISTORY_MAX_LENGTH} - *

- * Note: Setting this property will immediately - * enforce the specified max history size by dropping enough old - * historical records to enforce the desired size. Thus, any - * records that exceed the history size will be discarded and - * irreversibly lost. - *

- * - * @param historyMaxSize The max history size. - */ - public void setHistoryMaxSize(int historyMaxSize) { - synchronized (mInstanceLock) { - if (mHistoryMaxSize == historyMaxSize) { - return; - } - mHistoryMaxSize = historyMaxSize; - pruneExcessiveHistoricalRecordsLocked(); - sortActivities(); - } - } - - /** - * Gets the history max size. - * - * @return The history max size. - */ - public int getHistoryMaxSize() { - synchronized (mInstanceLock) { - return mHistoryMaxSize; - } - } - - /** - * Gets the history size. - * - * @return The history size. - */ - public int getHistorySize() { - synchronized (mInstanceLock) { - return mHistoricalRecords.size(); - } - } - - /** - * Adds a historical record. - * - * @param historicalRecord The record to add. - * @return True if the record was added. - */ - private boolean addHisoricalRecord(HistoricalRecord historicalRecord) { - synchronized (mInstanceLock) { - final boolean added = mHistoricalRecords.add(historicalRecord); - if (added) { - mHistoricalRecordsChanged = true; - pruneExcessiveHistoricalRecordsLocked(); - persistHistoricalData(); - sortActivities(); - } - return added; - } - } - - /** - * Prunes older excessive records to guarantee {@link #mHistoryMaxSize}. - */ - private void pruneExcessiveHistoricalRecordsLocked() { - List choiceRecords = mHistoricalRecords; - final int pruneCount = choiceRecords.size() - mHistoryMaxSize; - if (pruneCount <= 0) { - return; - } - mHistoricalRecordsChanged = true; - for (int i = 0; i < pruneCount; i++) { - HistoricalRecord prunedRecord = choiceRecords.remove(0); - if (DEBUG) { - Log.i(LOG_TAG, "Pruned: " + prunedRecord); - } - } - } - - /** - * Loads the activities. - */ - private void loadActivitiesLocked() { - mActivites.clear(); - if (mIntent != null) { - List resolveInfos = - mContext.getPackageManager().queryIntentActivities(mIntent, 0); - final int resolveInfoCount = resolveInfos.size(); - for (int i = 0; i < resolveInfoCount; i++) { - ResolveInfo resolveInfo = resolveInfos.get(i); - mActivites.add(new ActivityResolveInfo(resolveInfo)); - } - sortActivities(); - } else { - notifyChanged(); - } - } - - /** - * Represents a record in the history. - */ - public final static class HistoricalRecord { - - /** - * The activity name. - */ - public final ComponentName activity; - - /** - * The choice time. - */ - public final long time; - - /** - * The record weight. - */ - public final float weight; - - /** - * Creates a new instance. - * - * @param activityName The activity component name flattened to string. - * @param time The time the activity was chosen. - * @param weight The weight of the record. - */ - public HistoricalRecord(String activityName, long time, float weight) { - this(ComponentName.unflattenFromString(activityName), time, weight); - } - - /** - * Creates a new instance. - * - * @param activityName The activity name. - * @param time The time the activity was chosen. - * @param weight The weight of the record. - */ - public HistoricalRecord(ComponentName activityName, long time, float weight) { - this.activity = activityName; - this.time = time; - this.weight = weight; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((activity == null) ? 0 : activity.hashCode()); - result = prime * result + (int) (time ^ (time >>> 32)); - result = prime * result + Float.floatToIntBits(weight); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - HistoricalRecord other = (HistoricalRecord) obj; - if (activity == null) { - if (other.activity != null) { - return false; - } - } else if (!activity.equals(other.activity)) { - return false; - } - if (time != other.time) { - return false; - } - if (Float.floatToIntBits(weight) != Float.floatToIntBits(other.weight)) { - return false; - } - return true; - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("["); - builder.append("; activity:").append(activity); - builder.append("; time:").append(time); - builder.append("; weight:").append(new BigDecimal(weight)); - builder.append("]"); - return builder.toString(); - } - } - - /** - * Represents an activity. - */ - public final class ActivityResolveInfo implements Comparable { - - /** - * The {@link ResolveInfo} of the activity. - */ - public final ResolveInfo resolveInfo; - - /** - * Weight of the activity. Useful for sorting. - */ - public float weight; - - /** - * Creates a new instance. - * - * @param resolveInfo activity {@link ResolveInfo}. - */ - public ActivityResolveInfo(ResolveInfo resolveInfo) { - this.resolveInfo = resolveInfo; - } - - @Override - public int hashCode() { - return 31 + Float.floatToIntBits(weight); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - ActivityResolveInfo other = (ActivityResolveInfo) obj; - if (Float.floatToIntBits(weight) != Float.floatToIntBits(other.weight)) { - return false; - } - return true; - } - - public int compareTo(ActivityResolveInfo another) { - return Float.floatToIntBits(another.weight) - Float.floatToIntBits(weight); - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("["); - builder.append("resolveInfo:").append(resolveInfo.toString()); - builder.append("; weight:").append(new BigDecimal(weight)); - builder.append("]"); - return builder.toString(); - } - } - - /** - * Default activity sorter implementation. - */ - private final class DefaultSorter implements ActivitySorter { - private static final float WEIGHT_DECAY_COEFFICIENT = 0.95f; - - private final Map mPackageNameToActivityMap = - new HashMap(); - - public void sort(Intent intent, List activities, - List historicalRecords) { - Map packageNameToActivityMap = - mPackageNameToActivityMap; - packageNameToActivityMap.clear(); - - final int activityCount = activities.size(); - for (int i = 0; i < activityCount; i++) { - ActivityResolveInfo activity = activities.get(i); - activity.weight = 0.0f; - String packageName = activity.resolveInfo.activityInfo.packageName; - packageNameToActivityMap.put(packageName, activity); - } - - final int lastShareIndex = historicalRecords.size() - 1; - float nextRecordWeight = 1; - for (int i = lastShareIndex; i >= 0; i--) { - HistoricalRecord historicalRecord = historicalRecords.get(i); - String packageName = historicalRecord.activity.getPackageName(); - ActivityResolveInfo activity = packageNameToActivityMap.get(packageName); - if (activity != null) { - activity.weight += historicalRecord.weight * nextRecordWeight; - nextRecordWeight = nextRecordWeight * WEIGHT_DECAY_COEFFICIENT; - } - } - - Collections.sort(activities); - - if (DEBUG) { - for (int i = 0; i < activityCount; i++) { - Log.i(LOG_TAG, "Sorted: " + activities.get(i)); - } - } - } - } - - /** - * Command for reading the historical records from a file off the UI thread. - */ - private final class HistoryLoader implements Runnable { - - public void run() { - FileInputStream fis = null; - try { - fis = mContext.openFileInput(mHistoryFileName); - } catch (FileNotFoundException fnfe) { - if (DEBUG) { - Log.i(LOG_TAG, "Could not open historical records file: " + mHistoryFileName); - } - return; - } - try { - XmlPullParser parser = Xml.newPullParser(); - parser.setInput(fis, null); - - int type = XmlPullParser.START_DOCUMENT; - while (type != XmlPullParser.END_DOCUMENT && type != XmlPullParser.START_TAG) { - type = parser.next(); - } - - if (!TAG_HISTORICAL_RECORDS.equals(parser.getName())) { - throw new XmlPullParserException("Share records file does not start with " - + TAG_HISTORICAL_RECORDS + " tag."); - } - - List readRecords = new ArrayList(); - - while (true) { - type = parser.next(); - if (type == XmlPullParser.END_DOCUMENT) { - break; - } - if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { - continue; - } - String nodeName = parser.getName(); - if (!TAG_HISTORICAL_RECORD.equals(nodeName)) { - throw new XmlPullParserException("Share records file not well-formed."); - } - - String activity = parser.getAttributeValue(null, ATTRIBUTE_ACTIVITY); - final long time = - Long.parseLong(parser.getAttributeValue(null, ATTRIBUTE_TIME)); - final float weight = - Float.parseFloat(parser.getAttributeValue(null, ATTRIBUTE_WEIGHT)); - - HistoricalRecord readRecord = new HistoricalRecord(activity, time, - weight); - readRecords.add(readRecord); - - if (DEBUG) { - Log.i(LOG_TAG, "Read " + readRecord.toString()); - } - } - - if (DEBUG) { - Log.i(LOG_TAG, "Read " + readRecords.size() + " historical records."); - } - - synchronized (mInstanceLock) { - Set uniqueShareRecords = - new LinkedHashSet(readRecords); - - // Make sure no duplicates. Example: Read a file with - // one record, add one record, persist the two records, - // add a record, read the persisted records - the - // read two records should not be added again. - List historicalRecords = mHistoricalRecords; - final int historicalRecordsCount = historicalRecords.size(); - for (int i = historicalRecordsCount - 1; i >= 0; i--) { - HistoricalRecord historicalRecord = historicalRecords.get(i); - uniqueShareRecords.add(historicalRecord); - } - - if (historicalRecords.size() == uniqueShareRecords.size()) { - return; - } - - // Make sure the oldest records go to the end. - historicalRecords.clear(); - historicalRecords.addAll(uniqueShareRecords); - - mHistoricalRecordsChanged = true; - - // Do this on the client thread since the client may be on the UI - // thread, wait for data changes which happen during sorting, and - // perform UI modification based on the data change. - mHandler.post(new Runnable() { - public void run() { - pruneExcessiveHistoricalRecordsLocked(); - sortActivities(); - } - }); - } - } catch (XmlPullParserException xppe) { - Log.e(LOG_TAG, "Error reading historical recrod file: " + mHistoryFileName, xppe); - } catch (IOException ioe) { - Log.e(LOG_TAG, "Error reading historical recrod file: " + mHistoryFileName, ioe); - } finally { - if (fis != null) { - try { - fis.close(); - } catch (IOException ioe) { - /* ignore */ - } - } - } - } - } - - /** - * Command for persisting the historical records to a file off the UI thread. - */ - private final class HistoryPersister implements Runnable { - - public void run() { - FileOutputStream fos = null; - List records = null; - - synchronized (mInstanceLock) { - records = new ArrayList(mHistoricalRecords); - } - - try { - fos = mContext.openFileOutput(mHistoryFileName, Context.MODE_PRIVATE); - } catch (FileNotFoundException fnfe) { - Log.e(LOG_TAG, "Error writing historical recrod file: " + mHistoryFileName, fnfe); - return; - } - - XmlSerializer serializer = Xml.newSerializer(); - - try { - serializer.setOutput(fos, null); - serializer.startDocument("UTF-8", true); - serializer.startTag(null, TAG_HISTORICAL_RECORDS); - - final int recordCount = records.size(); - for (int i = 0; i < recordCount; i++) { - HistoricalRecord record = records.remove(0); - serializer.startTag(null, TAG_HISTORICAL_RECORD); - serializer.attribute(null, ATTRIBUTE_ACTIVITY, record.activity.flattenToString()); - serializer.attribute(null, ATTRIBUTE_TIME, String.valueOf(record.time)); - serializer.attribute(null, ATTRIBUTE_WEIGHT, String.valueOf(record.weight)); - serializer.endTag(null, TAG_HISTORICAL_RECORD); - if (DEBUG) { - Log.i(LOG_TAG, "Wrote " + record.toString()); - } - } - - serializer.endTag(null, TAG_HISTORICAL_RECORDS); - serializer.endDocument(); - - if (DEBUG) { - Log.i(LOG_TAG, "Wrote " + recordCount + " historical records."); - } - } catch (IllegalArgumentException iae) { - Log.e(LOG_TAG, "Error writing historical recrod file: " + mHistoryFileName, iae); - } catch (IllegalStateException ise) { - Log.e(LOG_TAG, "Error writing historical recrod file: " + mHistoryFileName, ise); - } catch (IOException ioe) { - Log.e(LOG_TAG, "Error writing historical recrod file: " + mHistoryFileName, ioe); - } finally { - if (fos != null) { - try { - fos.close(); - } catch (IOException e) { - /* ignore */ - } - } - } - } - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/widget/ActivityChooserView.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/widget/ActivityChooserView.java deleted file mode 100644 index da13bc99f..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/widget/ActivityChooserView.java +++ /dev/null @@ -1,818 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.widget; - -import android.os.Build; -import com.actionbarsherlock.R; -import com.actionbarsherlock.internal.widget.IcsLinearLayout; -import com.actionbarsherlock.internal.widget.IcsListPopupWindow; -import com.actionbarsherlock.view.ActionProvider; -import com.actionbarsherlock.widget.ActivityChooserModel.ActivityChooserModelClient; -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.content.res.Resources; -import android.content.res.TypedArray; -import android.database.DataSetObserver; -import android.graphics.drawable.Drawable; -import android.util.AttributeSet; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.view.ViewTreeObserver; -import android.view.ViewTreeObserver.OnGlobalLayoutListener; -import android.widget.AdapterView; -import android.widget.BaseAdapter; -import android.widget.FrameLayout; -import android.widget.ImageView; -import android.widget.PopupWindow; -import android.widget.TextView; - -/** - * This class is a view for choosing an activity for handling a given {@link Intent}. - *

- * The view is composed of two adjacent buttons: - *

    - *
  • - * The left button is an immediate action and allows one click activity choosing. - * Tapping this button immediately executes the intent without requiring any further - * user input. Long press on this button shows a popup for changing the default - * activity. - *
  • - *
  • - * The right button is an overflow action and provides an optimized menu - * of additional activities. Tapping this button shows a popup anchored to this - * view, listing the most frequently used activities. This list is initially - * limited to a small number of items in frequency used order. The last item, - * "Show all..." serves as an affordance to display all available activities. - *
  • - *
- *

- * - * @hide - */ -class ActivityChooserView extends ViewGroup implements ActivityChooserModelClient { - - /** - * An adapter for displaying the activities in an {@link AdapterView}. - */ - private final ActivityChooserViewAdapter mAdapter; - - /** - * Implementation of various interfaces to avoid publishing them in the APIs. - */ - private final Callbacks mCallbacks; - - /** - * The content of this view. - */ - private final IcsLinearLayout mActivityChooserContent; - - /** - * Stores the background drawable to allow hiding and latter showing. - */ - private final Drawable mActivityChooserContentBackground; - - /** - * The expand activities action button; - */ - private final FrameLayout mExpandActivityOverflowButton; - - /** - * The image for the expand activities action button; - */ - private final ImageView mExpandActivityOverflowButtonImage; - - /** - * The default activities action button; - */ - private final FrameLayout mDefaultActivityButton; - - /** - * The image for the default activities action button; - */ - private final ImageView mDefaultActivityButtonImage; - - /** - * The maximal width of the list popup. - */ - private final int mListPopupMaxWidth; - - /** - * The ActionProvider hosting this view, if applicable. - */ - ActionProvider mProvider; - - /** - * Observer for the model data. - */ - private final DataSetObserver mModelDataSetOberver = new DataSetObserver() { - - @Override - public void onChanged() { - super.onChanged(); - mAdapter.notifyDataSetChanged(); - } - @Override - public void onInvalidated() { - super.onInvalidated(); - mAdapter.notifyDataSetInvalidated(); - } - }; - - private final OnGlobalLayoutListener mOnGlobalLayoutListener = new OnGlobalLayoutListener() { - @Override - public void onGlobalLayout() { - if (isShowingPopup()) { - if (!isShown()) { - getListPopupWindow().dismiss(); - } else { - getListPopupWindow().show(); - if (mProvider != null) { - mProvider.subUiVisibilityChanged(true); - } - } - } - } - }; - - /** - * Popup window for showing the activity overflow list. - */ - private IcsListPopupWindow mListPopupWindow; - - /** - * Listener for the dismissal of the popup/alert. - */ - private PopupWindow.OnDismissListener mOnDismissListener; - - /** - * Flag whether a default activity currently being selected. - */ - private boolean mIsSelectingDefaultActivity; - - /** - * The count of activities in the popup. - */ - private int mInitialActivityCount = ActivityChooserViewAdapter.MAX_ACTIVITY_COUNT_DEFAULT; - - /** - * Flag whether this view is attached to a window. - */ - private boolean mIsAttachedToWindow; - - /** - * String resource for formatting content description of the default target. - */ - private int mDefaultActionButtonContentDescription; - - private final Context mContext; - - /** - * Create a new instance. - * - * @param context The application environment. - */ - public ActivityChooserView(Context context) { - this(context, null); - } - - /** - * Create a new instance. - * - * @param context The application environment. - * @param attrs A collection of attributes. - */ - public ActivityChooserView(Context context, AttributeSet attrs) { - this(context, attrs, 0); - } - - /** - * Create a new instance. - * - * @param context The application environment. - * @param attrs A collection of attributes. - * @param defStyle The default style to apply to this view. - */ - public ActivityChooserView(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - mContext = context; - - TypedArray attributesArray = context.obtainStyledAttributes(attrs, - R.styleable.SherlockActivityChooserView, defStyle, 0); - - mInitialActivityCount = attributesArray.getInt( - R.styleable.SherlockActivityChooserView_initialActivityCount, - ActivityChooserViewAdapter.MAX_ACTIVITY_COUNT_DEFAULT); - - Drawable expandActivityOverflowButtonDrawable = attributesArray.getDrawable( - R.styleable.SherlockActivityChooserView_expandActivityOverflowButtonDrawable); - - attributesArray.recycle(); - - LayoutInflater inflater = LayoutInflater.from(mContext); - inflater.inflate(R.layout.abs__activity_chooser_view, this, true); - - mCallbacks = new Callbacks(); - - mActivityChooserContent = (IcsLinearLayout) findViewById(R.id.abs__activity_chooser_view_content); - mActivityChooserContentBackground = mActivityChooserContent.getBackground(); - - mDefaultActivityButton = (FrameLayout) findViewById(R.id.abs__default_activity_button); - mDefaultActivityButton.setOnClickListener(mCallbacks); - mDefaultActivityButton.setOnLongClickListener(mCallbacks); - mDefaultActivityButtonImage = (ImageView) mDefaultActivityButton.findViewById(R.id.abs__image); - - mExpandActivityOverflowButton = (FrameLayout) findViewById(R.id.abs__expand_activities_button); - mExpandActivityOverflowButton.setOnClickListener(mCallbacks); - mExpandActivityOverflowButtonImage = - (ImageView) mExpandActivityOverflowButton.findViewById(R.id.abs__image); - mExpandActivityOverflowButtonImage.setImageDrawable(expandActivityOverflowButtonDrawable); - - mAdapter = new ActivityChooserViewAdapter(); - mAdapter.registerDataSetObserver(new DataSetObserver() { - @Override - public void onChanged() { - super.onChanged(); - updateAppearance(); - } - }); - - Resources resources = context.getResources(); - mListPopupMaxWidth = Math.max(resources.getDisplayMetrics().widthPixels / 2, - resources.getDimensionPixelSize(R.dimen.abs__config_prefDialogWidth)); - } - - /** - * {@inheritDoc} - */ - public void setActivityChooserModel(ActivityChooserModel dataModel) { - mAdapter.setDataModel(dataModel); - if (isShowingPopup()) { - dismissPopup(); - showPopup(); - } - } - - /** - * Sets the background for the button that expands the activity - * overflow list. - * - * Note: Clients would like to set this drawable - * as a clue about the action the chosen activity will perform. For - * example, if a share activity is to be chosen the drawable should - * give a clue that sharing is to be performed. - * - * @param drawable The drawable. - */ - public void setExpandActivityOverflowButtonDrawable(Drawable drawable) { - mExpandActivityOverflowButtonImage.setImageDrawable(drawable); - } - - /** - * Sets the content description for the button that expands the activity - * overflow list. - * - * description as a clue about the action performed by the button. - * For example, if a share activity is to be chosen the content - * description should be something like "Share with". - * - * @param resourceId The content description resource id. - */ - public void setExpandActivityOverflowButtonContentDescription(int resourceId) { - CharSequence contentDescription = mContext.getString(resourceId); - mExpandActivityOverflowButtonImage.setContentDescription(contentDescription); - } - - /** - * Set the provider hosting this view, if applicable. - * @hide Internal use only - */ - public void setProvider(ActionProvider provider) { - mProvider = provider; - } - - /** - * Shows the popup window with activities. - * - * @return True if the popup was shown, false if already showing. - */ - public boolean showPopup() { - if (isShowingPopup() || !mIsAttachedToWindow) { - return false; - } - mIsSelectingDefaultActivity = false; - showPopupUnchecked(mInitialActivityCount); - return true; - } - - /** - * Shows the popup no matter if it was already showing. - * - * @param maxActivityCount The max number of activities to display. - */ - private void showPopupUnchecked(int maxActivityCount) { - if (mAdapter.getDataModel() == null) { - throw new IllegalStateException("No data model. Did you call #setDataModel?"); - } - - getViewTreeObserver().addOnGlobalLayoutListener(mOnGlobalLayoutListener); - - final boolean defaultActivityButtonShown = - mDefaultActivityButton.getVisibility() == VISIBLE; - - final int activityCount = mAdapter.getActivityCount(); - final int maxActivityCountOffset = defaultActivityButtonShown ? 1 : 0; - if (maxActivityCount != ActivityChooserViewAdapter.MAX_ACTIVITY_COUNT_UNLIMITED - && activityCount > maxActivityCount + maxActivityCountOffset) { - mAdapter.setShowFooterView(true); - mAdapter.setMaxActivityCount(maxActivityCount - 1); - } else { - mAdapter.setShowFooterView(false); - mAdapter.setMaxActivityCount(maxActivityCount); - } - - IcsListPopupWindow popupWindow = getListPopupWindow(); - if (!popupWindow.isShowing()) { - if (mIsSelectingDefaultActivity || !defaultActivityButtonShown) { - mAdapter.setShowDefaultActivity(true, defaultActivityButtonShown); - } else { - mAdapter.setShowDefaultActivity(false, false); - } - final int contentWidth = Math.min(mAdapter.measureContentWidth(), mListPopupMaxWidth); - popupWindow.setContentWidth(contentWidth); - popupWindow.show(); - if (mProvider != null) { - mProvider.subUiVisibilityChanged(true); - } - popupWindow.getListView().setContentDescription(mContext.getString( - R.string.abs__activitychooserview_choose_application)); - } - } - - /** - * Dismisses the popup window with activities. - * - * @return True if dismissed, false if already dismissed. - */ - public boolean dismissPopup() { - if (isShowingPopup()) { - getListPopupWindow().dismiss(); - ViewTreeObserver viewTreeObserver = getViewTreeObserver(); - if (viewTreeObserver.isAlive()) { - viewTreeObserver.removeGlobalOnLayoutListener(mOnGlobalLayoutListener); - } - } - return true; - } - - /** - * Gets whether the popup window with activities is shown. - * - * @return True if the popup is shown. - */ - public boolean isShowingPopup() { - return getListPopupWindow().isShowing(); - } - - @Override - protected void onAttachedToWindow() { - super.onAttachedToWindow(); - ActivityChooserModel dataModel = mAdapter.getDataModel(); - if (dataModel != null) { - dataModel.registerObserver(mModelDataSetOberver); - } - mIsAttachedToWindow = true; - } - - @Override - protected void onDetachedFromWindow() { - super.onDetachedFromWindow(); - ActivityChooserModel dataModel = mAdapter.getDataModel(); - if (dataModel != null) { - dataModel.unregisterObserver(mModelDataSetOberver); - } - ViewTreeObserver viewTreeObserver = getViewTreeObserver(); - if (viewTreeObserver.isAlive()) { - viewTreeObserver.removeGlobalOnLayoutListener(mOnGlobalLayoutListener); - } - mIsAttachedToWindow = false; - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - View child = mActivityChooserContent; - // If the default action is not visible we want to be as tall as the - // ActionBar so if this widget is used in the latter it will look as - // a normal action button. - if (mDefaultActivityButton.getVisibility() != VISIBLE) { - heightMeasureSpec = MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(heightMeasureSpec), - MeasureSpec.EXACTLY); - } - measureChild(child, widthMeasureSpec, heightMeasureSpec); - setMeasuredDimension(child.getMeasuredWidth(), child.getMeasuredHeight()); - } - - @Override - protected void onLayout(boolean changed, int left, int top, int right, int bottom) { - mActivityChooserContent.layout(0, 0, right - left, bottom - top); - if (getListPopupWindow().isShowing()) { - showPopupUnchecked(mAdapter.getMaxActivityCount()); - } else { - dismissPopup(); - } - } - - public ActivityChooserModel getDataModel() { - return mAdapter.getDataModel(); - } - - /** - * Sets a listener to receive a callback when the popup is dismissed. - * - * @param listener The listener to be notified. - */ - public void setOnDismissListener(PopupWindow.OnDismissListener listener) { - mOnDismissListener = listener; - } - - /** - * Sets the initial count of items shown in the activities popup - * i.e. the items before the popup is expanded. This is an upper - * bound since it is not guaranteed that such number of intent - * handlers exist. - * - * @param itemCount The initial popup item count. - */ - public void setInitialActivityCount(int itemCount) { - mInitialActivityCount = itemCount; - } - - /** - * Sets a content description of the default action button. This - * resource should be a string taking one formatting argument and - * will be used for formatting the content description of the button - * dynamically as the default target changes. For example, a resource - * pointing to the string "share with %1$s" will result in a content - * description "share with Bluetooth" for the Bluetooth activity. - * - * @param resourceId The resource id. - */ - public void setDefaultActionButtonContentDescription(int resourceId) { - mDefaultActionButtonContentDescription = resourceId; - } - - /** - * Gets the list popup window which is lazily initialized. - * - * @return The popup. - */ - private IcsListPopupWindow getListPopupWindow() { - if (mListPopupWindow == null) { - mListPopupWindow = new IcsListPopupWindow(getContext()); - mListPopupWindow.setAdapter(mAdapter); - mListPopupWindow.setAnchorView(ActivityChooserView.this); - mListPopupWindow.setModal(true); - mListPopupWindow.setOnItemClickListener(mCallbacks); - mListPopupWindow.setOnDismissListener(mCallbacks); - } - return mListPopupWindow; - } - - /** - * Updates the buttons state. - */ - private void updateAppearance() { - // Expand overflow button. - if (mAdapter.getCount() > 0) { - mExpandActivityOverflowButton.setEnabled(true); - } else { - mExpandActivityOverflowButton.setEnabled(false); - } - // Default activity button. - final int activityCount = mAdapter.getActivityCount(); - final int historySize = mAdapter.getHistorySize(); - if (activityCount > 0 && historySize > 0) { - mDefaultActivityButton.setVisibility(VISIBLE); - ResolveInfo activity = mAdapter.getDefaultActivity(); - PackageManager packageManager = mContext.getPackageManager(); - mDefaultActivityButtonImage.setImageDrawable(activity.loadIcon(packageManager)); - if (mDefaultActionButtonContentDescription != 0) { - CharSequence label = activity.loadLabel(packageManager); - String contentDescription = mContext.getString( - mDefaultActionButtonContentDescription, label); - mDefaultActivityButton.setContentDescription(contentDescription); - } - } else { - mDefaultActivityButton.setVisibility(View.GONE); - } - // Activity chooser content. - if (mDefaultActivityButton.getVisibility() == VISIBLE) { - mActivityChooserContent.setBackgroundDrawable(mActivityChooserContentBackground); - } else { - mActivityChooserContent.setBackgroundDrawable(null); - } - } - - /** - * Interface implementation to avoid publishing them in the APIs. - */ - private class Callbacks implements AdapterView.OnItemClickListener, - View.OnClickListener, View.OnLongClickListener, PopupWindow.OnDismissListener { - - // AdapterView#OnItemClickListener - public void onItemClick(AdapterView parent, View view, int position, long id) { - ActivityChooserViewAdapter adapter = (ActivityChooserViewAdapter) parent.getAdapter(); - final int itemViewType = adapter.getItemViewType(position); - switch (itemViewType) { - case ActivityChooserViewAdapter.ITEM_VIEW_TYPE_FOOTER: { - showPopupUnchecked(ActivityChooserViewAdapter.MAX_ACTIVITY_COUNT_UNLIMITED); - } break; - case ActivityChooserViewAdapter.ITEM_VIEW_TYPE_ACTIVITY: { - dismissPopup(); - if (mIsSelectingDefaultActivity) { - // The item at position zero is the default already. - if (position > 0) { - mAdapter.getDataModel().setDefaultActivity(position); - } - } else { - // If the default target is not shown in the list, the first - // item in the model is default action => adjust index - position = mAdapter.getShowDefaultActivity() ? position : position + 1; - Intent launchIntent = mAdapter.getDataModel().chooseActivity(position); - if (launchIntent != null) { - mContext.startActivity(launchIntent); - } - } - } break; - default: - throw new IllegalArgumentException(); - } - } - - // View.OnClickListener - public void onClick(View view) { - if (view == mDefaultActivityButton) { - dismissPopup(); - ResolveInfo defaultActivity = mAdapter.getDefaultActivity(); - final int index = mAdapter.getDataModel().getActivityIndex(defaultActivity); - Intent launchIntent = mAdapter.getDataModel().chooseActivity(index); - if (launchIntent != null) { - mContext.startActivity(launchIntent); - } - } else if (view == mExpandActivityOverflowButton) { - mIsSelectingDefaultActivity = false; - showPopupUnchecked(mInitialActivityCount); - } else { - throw new IllegalArgumentException(); - } - } - - // OnLongClickListener#onLongClick - @Override - public boolean onLongClick(View view) { - if (view == mDefaultActivityButton) { - if (mAdapter.getCount() > 0) { - mIsSelectingDefaultActivity = true; - showPopupUnchecked(mInitialActivityCount); - } - } else { - throw new IllegalArgumentException(); - } - return true; - } - - // PopUpWindow.OnDismissListener#onDismiss - public void onDismiss() { - notifyOnDismissListener(); - if (mProvider != null) { - mProvider.subUiVisibilityChanged(false); - } - } - - private void notifyOnDismissListener() { - if (mOnDismissListener != null) { - mOnDismissListener.onDismiss(); - } - } - } - - private static class SetActivated { - public static void invoke(View view, boolean activated) { - view.setActivated(activated); - } - } - - private static final boolean IS_HONEYCOMB = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB; - - /** - * Adapter for backing the list of activities shown in the popup. - */ - private class ActivityChooserViewAdapter extends BaseAdapter { - - public static final int MAX_ACTIVITY_COUNT_UNLIMITED = Integer.MAX_VALUE; - - public static final int MAX_ACTIVITY_COUNT_DEFAULT = 4; - - private static final int ITEM_VIEW_TYPE_ACTIVITY = 0; - - private static final int ITEM_VIEW_TYPE_FOOTER = 1; - - private static final int ITEM_VIEW_TYPE_COUNT = 3; - - private ActivityChooserModel mDataModel; - - private int mMaxActivityCount = MAX_ACTIVITY_COUNT_DEFAULT; - - private boolean mShowDefaultActivity; - - private boolean mHighlightDefaultActivity; - - private boolean mShowFooterView; - - public void setDataModel(ActivityChooserModel dataModel) { - ActivityChooserModel oldDataModel = mAdapter.getDataModel(); - if (oldDataModel != null && isShown()) { - oldDataModel.unregisterObserver(mModelDataSetOberver); - } - mDataModel = dataModel; - if (dataModel != null && isShown()) { - dataModel.registerObserver(mModelDataSetOberver); - } - notifyDataSetChanged(); - } - - @Override - public int getItemViewType(int position) { - if (mShowFooterView && position == getCount() - 1) { - return ITEM_VIEW_TYPE_FOOTER; - } else { - return ITEM_VIEW_TYPE_ACTIVITY; - } - } - - @Override - public int getViewTypeCount() { - return ITEM_VIEW_TYPE_COUNT; - } - - public int getCount() { - int count = 0; - int activityCount = mDataModel.getActivityCount(); - if (!mShowDefaultActivity && mDataModel.getDefaultActivity() != null) { - activityCount--; - } - count = Math.min(activityCount, mMaxActivityCount); - if (mShowFooterView) { - count++; - } - return count; - } - - public Object getItem(int position) { - final int itemViewType = getItemViewType(position); - switch (itemViewType) { - case ITEM_VIEW_TYPE_FOOTER: - return null; - case ITEM_VIEW_TYPE_ACTIVITY: - if (!mShowDefaultActivity && mDataModel.getDefaultActivity() != null) { - position++; - } - return mDataModel.getActivity(position); - default: - throw new IllegalArgumentException(); - } - } - - public long getItemId(int position) { - return position; - } - - public View getView(int position, View convertView, ViewGroup parent) { - final int itemViewType = getItemViewType(position); - switch (itemViewType) { - case ITEM_VIEW_TYPE_FOOTER: - if (convertView == null || convertView.getId() != ITEM_VIEW_TYPE_FOOTER) { - convertView = LayoutInflater.from(getContext()).inflate( - R.layout.abs__activity_chooser_view_list_item, parent, false); - convertView.setId(ITEM_VIEW_TYPE_FOOTER); - TextView titleView = (TextView) convertView.findViewById(R.id.abs__title); - titleView.setText(mContext.getString( - R.string.abs__activity_chooser_view_see_all)); - } - return convertView; - case ITEM_VIEW_TYPE_ACTIVITY: - if (convertView == null || convertView.getId() != R.id.abs__list_item) { - convertView = LayoutInflater.from(getContext()).inflate( - R.layout.abs__activity_chooser_view_list_item, parent, false); - } - PackageManager packageManager = mContext.getPackageManager(); - // Set the icon - ImageView iconView = (ImageView) convertView.findViewById(R.id.abs__icon); - ResolveInfo activity = (ResolveInfo) getItem(position); - iconView.setImageDrawable(activity.loadIcon(packageManager)); - // Set the title. - TextView titleView = (TextView) convertView.findViewById(R.id.abs__title); - titleView.setText(activity.loadLabel(packageManager)); - if (IS_HONEYCOMB) { - // Highlight the default. - if (mShowDefaultActivity && position == 0 && mHighlightDefaultActivity) { - SetActivated.invoke(convertView, true); - } else { - SetActivated.invoke(convertView, false); - } - } - return convertView; - default: - throw new IllegalArgumentException(); - } - } - - public int measureContentWidth() { - // The user may have specified some of the target not to be shown but we - // want to measure all of them since after expansion they should fit. - final int oldMaxActivityCount = mMaxActivityCount; - mMaxActivityCount = MAX_ACTIVITY_COUNT_UNLIMITED; - - int contentWidth = 0; - View itemView = null; - - final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); - final int heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); - final int count = getCount(); - - for (int i = 0; i < count; i++) { - itemView = getView(i, itemView, null); - itemView.measure(widthMeasureSpec, heightMeasureSpec); - contentWidth = Math.max(contentWidth, itemView.getMeasuredWidth()); - } - - mMaxActivityCount = oldMaxActivityCount; - - return contentWidth; - } - - public void setMaxActivityCount(int maxActivityCount) { - if (mMaxActivityCount != maxActivityCount) { - mMaxActivityCount = maxActivityCount; - notifyDataSetChanged(); - } - } - - public ResolveInfo getDefaultActivity() { - return mDataModel.getDefaultActivity(); - } - - public void setShowFooterView(boolean showFooterView) { - if (mShowFooterView != showFooterView) { - mShowFooterView = showFooterView; - notifyDataSetChanged(); - } - } - - public int getActivityCount() { - return mDataModel.getActivityCount(); - } - - public int getHistorySize() { - return mDataModel.getHistorySize(); - } - - public int getMaxActivityCount() { - return mMaxActivityCount; - } - - public ActivityChooserModel getDataModel() { - return mDataModel; - } - - public void setShowDefaultActivity(boolean showDefaultActivity, - boolean highlightDefaultActivity) { - if (mShowDefaultActivity != showDefaultActivity - || mHighlightDefaultActivity != highlightDefaultActivity) { - mShowDefaultActivity = showDefaultActivity; - mHighlightDefaultActivity = highlightDefaultActivity; - notifyDataSetChanged(); - } - } - - public boolean getShowDefaultActivity() { - return mShowDefaultActivity; - } - } -} diff --git a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/widget/ShareActionProvider.java b/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/widget/ShareActionProvider.java deleted file mode 100644 index 83e9f0ca9..000000000 --- a/android-libraries/ActionBarSherlock/src/com/actionbarsherlock/widget/ShareActionProvider.java +++ /dev/null @@ -1,316 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.widget; - -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.graphics.drawable.Drawable; -import android.util.TypedValue; -import android.view.View; - -import com.actionbarsherlock.R; -import com.actionbarsherlock.view.ActionProvider; -import com.actionbarsherlock.view.Menu; -import com.actionbarsherlock.view.MenuItem; -import com.actionbarsherlock.view.MenuItem.OnMenuItemClickListener; -import com.actionbarsherlock.view.SubMenu; -import com.actionbarsherlock.widget.ActivityChooserModel.OnChooseActivityListener; - -/** - * This is a provider for a share action. It is responsible for creating views - * that enable data sharing and also to show a sub menu with sharing activities - * if the hosting item is placed on the overflow menu. - *

- * Here is how to use the action provider with custom backing file in a {@link MenuItem}: - *

- *

- *

- * 
- *  // In Activity#onCreateOptionsMenu
- *  public boolean onCreateOptionsMenu(Menu menu) {
- *      // Get the menu item.
- *      MenuItem menuItem = menu.findItem(R.id.my_menu_item);
- *      // Get the provider and hold onto it to set/change the share intent.
- *      mShareActionProvider = (ShareActionProvider) menuItem.getActionProvider();
- *      // Set history different from the default before getting the action
- *      // view since a call to {@link MenuItem#getActionView() MenuItem.getActionView()} calls
- *      // {@link ActionProvider#onCreateActionView()} which uses the backing file name. Omit this
- *      // line if using the default share history file is desired.
- *      mShareActionProvider.setShareHistoryFileName("custom_share_history.xml");
- *      . . .
- *  }
- *
- *  // Somewhere in the application.
- *  public void doShare(Intent shareIntent) {
- *      // When you want to share set the share intent.
- *      mShareActionProvider.setShareIntent(shareIntent);
- *  }
- * 
- * - *

- *

- * Note: While the sample snippet demonstrates how to use this provider - * in the context of a menu item, the use of the provider is not limited to menu items. - *

- * - * @see ActionProvider - */ -public class ShareActionProvider extends ActionProvider { - - /** - * Listener for the event of selecting a share target. - */ - public interface OnShareTargetSelectedListener { - - /** - * Called when a share target has been selected. The client can - * decide whether to handle the intent or rely on the default - * behavior which is launching it. - *

- * Note: Modifying the intent is not permitted and - * any changes to the latter will be ignored. - *

- * - * @param source The source of the notification. - * @param intent The intent for launching the chosen share target. - * @return Whether the client has handled the intent. - */ - public boolean onShareTargetSelected(ShareActionProvider source, Intent intent); - } - - /** - * The default for the maximal number of activities shown in the sub-menu. - */ - private static final int DEFAULT_INITIAL_ACTIVITY_COUNT = 4; - - /** - * The the maximum number activities shown in the sub-menu. - */ - private int mMaxShownActivityCount = DEFAULT_INITIAL_ACTIVITY_COUNT; - - /** - * Listener for handling menu item clicks. - */ - private final ShareMenuItemOnMenuItemClickListener mOnMenuItemClickListener = - new ShareMenuItemOnMenuItemClickListener(); - - /** - * The default name for storing share history. - */ - public static final String DEFAULT_SHARE_HISTORY_FILE_NAME = "share_history.xml"; - - /** - * Context for accessing resources. - */ - private final Context mContext; - - /** - * The name of the file with share history data. - */ - private String mShareHistoryFileName = DEFAULT_SHARE_HISTORY_FILE_NAME; - - private OnShareTargetSelectedListener mOnShareTargetSelectedListener; - - private OnChooseActivityListener mOnChooseActivityListener; - - /** - * Creates a new instance. - * - * @param context Context for accessing resources. - */ - public ShareActionProvider(Context context) { - super(context); - mContext = context; - } - - /** - * Sets a listener to be notified when a share target has been selected. - * The listener can optionally decide to handle the selection and - * not rely on the default behavior which is to launch the activity. - *

- * Note: If you choose the backing share history file - * you will still be notified in this callback. - *

- * @param listener The listener. - */ - public void setOnShareTargetSelectedListener(OnShareTargetSelectedListener listener) { - mOnShareTargetSelectedListener = listener; - setActivityChooserPolicyIfNeeded(); - } - - /** - * {@inheritDoc} - */ - @Override - public View onCreateActionView() { - // Create the view and set its data model. - ActivityChooserModel dataModel = ActivityChooserModel.get(mContext, mShareHistoryFileName); - ActivityChooserView activityChooserView = new ActivityChooserView(mContext); - activityChooserView.setActivityChooserModel(dataModel); - - // Lookup and set the expand action icon. - TypedValue outTypedValue = new TypedValue(); - mContext.getTheme().resolveAttribute(R.attr.actionModeShareDrawable, outTypedValue, true); - Drawable drawable = mContext.getResources().getDrawable(outTypedValue.resourceId); - activityChooserView.setExpandActivityOverflowButtonDrawable(drawable); - activityChooserView.setProvider(this); - - // Set content description. - activityChooserView.setDefaultActionButtonContentDescription( - R.string.abs__shareactionprovider_share_with_application); - activityChooserView.setExpandActivityOverflowButtonContentDescription( - R.string.abs__shareactionprovider_share_with); - - return activityChooserView; - } - - /** - * {@inheritDoc} - */ - @Override - public boolean hasSubMenu() { - return true; - } - - /** - * {@inheritDoc} - */ - @Override - public void onPrepareSubMenu(SubMenu subMenu) { - // Clear since the order of items may change. - subMenu.clear(); - - ActivityChooserModel dataModel = ActivityChooserModel.get(mContext, mShareHistoryFileName); - PackageManager packageManager = mContext.getPackageManager(); - - final int expandedActivityCount = dataModel.getActivityCount(); - final int collapsedActivityCount = Math.min(expandedActivityCount, mMaxShownActivityCount); - - // Populate the sub-menu with a sub set of the activities. - for (int i = 0; i < collapsedActivityCount; i++) { - ResolveInfo activity = dataModel.getActivity(i); - subMenu.add(0, i, i, activity.loadLabel(packageManager)) - .setIcon(activity.loadIcon(packageManager)) - .setOnMenuItemClickListener(mOnMenuItemClickListener); - } - - if (collapsedActivityCount < expandedActivityCount) { - // Add a sub-menu for showing all activities as a list item. - SubMenu expandedSubMenu = subMenu.addSubMenu(Menu.NONE, collapsedActivityCount, - collapsedActivityCount, - mContext.getString(R.string.abs__activity_chooser_view_see_all)); - for (int i = 0; i < expandedActivityCount; i++) { - ResolveInfo activity = dataModel.getActivity(i); - expandedSubMenu.add(0, i, i, activity.loadLabel(packageManager)) - .setIcon(activity.loadIcon(packageManager)) - .setOnMenuItemClickListener(mOnMenuItemClickListener); - } - } - } - - /** - * Sets the file name of a file for persisting the share history which - * history will be used for ordering share targets. This file will be used - * for all view created by {@link #onCreateActionView()}. Defaults to - * {@link #DEFAULT_SHARE_HISTORY_FILE_NAME}. Set to null - * if share history should not be persisted between sessions. - *

- * Note: The history file name can be set any time, however - * only the action views created by {@link #onCreateActionView()} after setting - * the file name will be backed by the provided file. - *

- * - * @param shareHistoryFile The share history file name. - */ - public void setShareHistoryFileName(String shareHistoryFile) { - mShareHistoryFileName = shareHistoryFile; - setActivityChooserPolicyIfNeeded(); - } - - /** - * Sets an intent with information about the share action. Here is a - * sample for constructing a share intent: - *

- *

-     * 
-     *  Intent shareIntent = new Intent(Intent.ACTION_SEND);
-     *  shareIntent.setType("image/*");
-     *  Uri uri = Uri.fromFile(new File(getFilesDir(), "foo.jpg"));
-     *  shareIntent.putExtra(Intent.EXTRA_STREAM, uri.toString());
-     * 
- * - *

- * - * @param shareIntent The share intent. - * - * @see Intent#ACTION_SEND - * @see Intent#ACTION_SEND_MULTIPLE - */ - public void setShareIntent(Intent shareIntent) { - ActivityChooserModel dataModel = ActivityChooserModel.get(mContext, - mShareHistoryFileName); - dataModel.setIntent(shareIntent); - } - - /** - * Reusable listener for handling share item clicks. - */ - private class ShareMenuItemOnMenuItemClickListener implements OnMenuItemClickListener { - @Override - public boolean onMenuItemClick(MenuItem item) { - ActivityChooserModel dataModel = ActivityChooserModel.get(mContext, - mShareHistoryFileName); - final int itemId = item.getItemId(); - Intent launchIntent = dataModel.chooseActivity(itemId); - if (launchIntent != null) { - mContext.startActivity(launchIntent); - } - return true; - } - } - - /** - * Set the activity chooser policy of the model backed by the current - * share history file if needed which is if there is a registered callback. - */ - private void setActivityChooserPolicyIfNeeded() { - if (mOnShareTargetSelectedListener == null) { - return; - } - if (mOnChooseActivityListener == null) { - mOnChooseActivityListener = new ShareAcitivityChooserModelPolicy(); - } - ActivityChooserModel dataModel = ActivityChooserModel.get(mContext, mShareHistoryFileName); - dataModel.setOnChooseActivityListener(mOnChooseActivityListener); - } - - /** - * Policy that delegates to the {@link OnShareTargetSelectedListener}, if such. - */ - private class ShareAcitivityChooserModelPolicy implements OnChooseActivityListener { - @Override - public boolean onChooseActivity(ActivityChooserModel host, Intent intent) { - if (mOnShareTargetSelectedListener != null) { - return mOnShareTargetSelectedListener.onShareTargetSelected( - ShareActionProvider.this, intent); - } - return false; - } - } -} diff --git a/android-libraries/TreeViewList/.classpath b/android-libraries/TreeViewList/.classpath deleted file mode 100644 index a4f1e4054..000000000 --- a/android-libraries/TreeViewList/.classpath +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/android-libraries/TreeViewList/.project b/android-libraries/TreeViewList/.project deleted file mode 100644 index c9d4fdacc..000000000 --- a/android-libraries/TreeViewList/.project +++ /dev/null @@ -1,33 +0,0 @@ - - - TreeViewList - - - - - - com.android.ide.eclipse.adt.ResourceManagerBuilder - - - - - com.android.ide.eclipse.adt.PreCompilerBuilder - - - - - org.eclipse.jdt.core.javabuilder - - - - - com.android.ide.eclipse.adt.ApkBuilder - - - - - - com.android.ide.eclipse.adt.AndroidNature - org.eclipse.jdt.core.javanature - - diff --git a/android-libraries/TreeViewList/AndroidManifest.xml b/android-libraries/TreeViewList/AndroidManifest.xml deleted file mode 100644 index 28a7fe08e..000000000 --- a/android-libraries/TreeViewList/AndroidManifest.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/android-libraries/TreeViewList/gen/pl/polidea/treeview/BuildConfig.java b/android-libraries/TreeViewList/gen/pl/polidea/treeview/BuildConfig.java deleted file mode 100644 index 18bc91b3b..000000000 --- a/android-libraries/TreeViewList/gen/pl/polidea/treeview/BuildConfig.java +++ /dev/null @@ -1,6 +0,0 @@ -/** Automatically generated file. DO NOT MODIFY */ -package pl.polidea.treeview; - -public final class BuildConfig { - public final static boolean DEBUG = true; -} \ No newline at end of file diff --git a/android-libraries/TreeViewList/gen/pl/polidea/treeview/R.java b/android-libraries/TreeViewList/gen/pl/polidea/treeview/R.java deleted file mode 100644 index 3ef9b3547..000000000 --- a/android-libraries/TreeViewList/gen/pl/polidea/treeview/R.java +++ /dev/null @@ -1,276 +0,0 @@ -/* AUTO-GENERATED FILE. DO NOT MODIFY. - * - * This class was automatically generated by the - * aapt tool from the resource data it found. It - * should not be modified by hand. - */ - -package pl.polidea.treeview; - -public final class R { - public static final class attr { - /**

Must be a boolean value, either "true" or "false". -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. - */ - public static int collapsible=0x7f010000; - /**

Must be a boolean value, either "true" or "false". -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. - */ - public static int handle_trackball_press=0x7f010004; - /**

Must be a dimension value, which is a floating point number appended with a unit such as "14.5sp". -Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size), -in (inches), mm (millimeters). -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. - */ - public static int indent_width=0x7f010003; - /**

May be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

May be a color value, in the form of "#rgb", "#argb", -"#rrggbb", or "#aarrggbb". - */ - public static int indicator_background=0x7f010006; - /**

Must be one or more (separated by '|') of the following constant values.

- ---- - - - - - - - - - - - - -
ConstantValueDescription
top0x30 Push object to the top of its container, not changing its size.
bottom0x50 Push object to the bottom of its container, not changing its size.
left0x03 Push object to the left of its container, not changing its size.
right0x05 Push object to the right of its container, not changing its size.
center_vertical0x10 Place object in the vertical center of its container, not changing its size.
fill_vertical0x70 Grow the vertical size of the object if needed so it completely fills its container.
center_horizontal0x01 Place object in the horizontal center of its container, not changing its size.
fill_horizontal0x07 Grow the horizontal size of the object if needed so it completely fills its container.
center0x11 Place the object in the center of its container in both the vertical and horizontal axis, not changing its size.
fill0x77 Grow the horizontal and vertical size of the object if needed so it completely fills its container.
clip_vertical0x80 Additional option that can be set to have the top and/or bottom edges of the child clipped to its container's bounds. - The clip will be based on the vertical gravity: a top gravity will clip the bottom edge, a bottom gravity will clip the top - edge, and neither will clip both edges.
clip_horizontal0x08 Additional option that can be set to have the left and/or right edges of the child clipped to its container's bounds. - The clip will be based on the horizontal gravity: a left gravity will clip the right edge, a right gravity will clip the - left edge, and neither will clip both edges.
- */ - public static int indicator_gravity=0x7f010005; - /**

May be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

May be a color value, in the form of "#rgb", "#argb", -"#rrggbb", or "#aarrggbb". - */ - public static int row_background=0x7f010007; - /**

May be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

May be a color value, in the form of "#rgb", "#argb", -"#rrggbb", or "#aarrggbb". - */ - public static int src_collapsed=0x7f010002; - /**

May be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

May be a color value, in the form of "#rgb", "#argb", -"#rrggbb", or "#aarrggbb". - */ - public static int src_expanded=0x7f010001; - } - public static final class drawable { - public static int collapsed=0x7f020000; - public static int divider=0x7f020001; - public static int expanded=0x7f020002; - public static int ic_launcher=0x7f020003; - public static int list_selector_background=0x7f020004; - public static int list_selector_background_disabled=0x7f020005; - public static int list_selector_background_focus=0x7f020006; - public static int list_selector_background_longpress=0x7f020007; - public static int list_selector_background_pressed=0x7f020008; - public static int list_selector_background_transition=0x7f020009; - } - public static final class id { - public static int bottom=0x7f040001; - public static int center=0x7f040008; - public static int center_horizontal=0x7f040006; - public static int center_vertical=0x7f040004; - public static int clip_horizontal=0x7f04000b; - public static int clip_vertical=0x7f04000a; - public static int fill=0x7f040009; - public static int fill_horizontal=0x7f040007; - public static int fill_vertical=0x7f040005; - public static int left=0x7f040002; - public static int right=0x7f040003; - public static int top=0x7f040000; - public static int treeview_list_item_frame=0x7f04000e; - public static int treeview_list_item_image=0x7f04000d; - public static int treeview_list_item_image_layout=0x7f04000c; - } - public static final class layout { - public static int tree_list_item_wrapper=0x7f030000; - } - public static final class style { - public static int treeViewListStyle=0x7f050000; - } - public static final class styleable { - /** Attributes that can be used with a TreeViewList. -

Includes the following attributes:

- - - - - - - - - - - - -
AttributeDescription
{@link #TreeViewList_collapsible pl.polidea.treeview:collapsible}
{@link #TreeViewList_handle_trackball_press pl.polidea.treeview:handle_trackball_press}
{@link #TreeViewList_indent_width pl.polidea.treeview:indent_width}
{@link #TreeViewList_indicator_background pl.polidea.treeview:indicator_background}
{@link #TreeViewList_indicator_gravity pl.polidea.treeview:indicator_gravity}
{@link #TreeViewList_row_background pl.polidea.treeview:row_background}
{@link #TreeViewList_src_collapsed pl.polidea.treeview:src_collapsed}
{@link #TreeViewList_src_expanded pl.polidea.treeview:src_expanded}
- @see #TreeViewList_collapsible - @see #TreeViewList_handle_trackball_press - @see #TreeViewList_indent_width - @see #TreeViewList_indicator_background - @see #TreeViewList_indicator_gravity - @see #TreeViewList_row_background - @see #TreeViewList_src_collapsed - @see #TreeViewList_src_expanded - */ - public static final int[] TreeViewList = { - 0x7f010000, 0x7f010001, 0x7f010002, 0x7f010003, - 0x7f010004, 0x7f010005, 0x7f010006, 0x7f010007 - }; - /** -

This symbol is the offset where the {@link pl.polidea.treeview.R.attr#collapsible} - attribute's value can be found in the {@link #TreeViewList} array. - - -

Must be a boolean value, either "true" or "false". -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. - @attr name android:collapsible - */ - public static final int TreeViewList_collapsible = 0; - /** -

This symbol is the offset where the {@link pl.polidea.treeview.R.attr#handle_trackball_press} - attribute's value can be found in the {@link #TreeViewList} array. - - -

Must be a boolean value, either "true" or "false". -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. - @attr name android:handle_trackball_press - */ - public static final int TreeViewList_handle_trackball_press = 4; - /** -

This symbol is the offset where the {@link pl.polidea.treeview.R.attr#indent_width} - attribute's value can be found in the {@link #TreeViewList} array. - - -

Must be a dimension value, which is a floating point number appended with a unit such as "14.5sp". -Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size), -in (inches), mm (millimeters). -

This may also be a reference to a resource (in the form -"@[package:]type:name") or -theme attribute (in the form -"?[package:][type:]name") -containing a value of this type. - @attr name android:indent_width - */ - public static final int TreeViewList_indent_width = 3; - /** -

This symbol is the offset where the {@link pl.polidea.treeview.R.attr#indicator_background} - attribute's value can be found in the {@link #TreeViewList} array. - - -

May be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

May be a color value, in the form of "#rgb", "#argb", -"#rrggbb", or "#aarrggbb". - @attr name android:indicator_background - */ - public static final int TreeViewList_indicator_background = 6; - /** -

This symbol is the offset where the {@link pl.polidea.treeview.R.attr#indicator_gravity} - attribute's value can be found in the {@link #TreeViewList} array. - - -

Must be one or more (separated by '|') of the following constant values.

- ---- - - - - - - - - - - - - -
ConstantValueDescription
top0x30 Push object to the top of its container, not changing its size.
bottom0x50 Push object to the bottom of its container, not changing its size.
left0x03 Push object to the left of its container, not changing its size.
right0x05 Push object to the right of its container, not changing its size.
center_vertical0x10 Place object in the vertical center of its container, not changing its size.
fill_vertical0x70 Grow the vertical size of the object if needed so it completely fills its container.
center_horizontal0x01 Place object in the horizontal center of its container, not changing its size.
fill_horizontal0x07 Grow the horizontal size of the object if needed so it completely fills its container.
center0x11 Place the object in the center of its container in both the vertical and horizontal axis, not changing its size.
fill0x77 Grow the horizontal and vertical size of the object if needed so it completely fills its container.
clip_vertical0x80 Additional option that can be set to have the top and/or bottom edges of the child clipped to its container's bounds. - The clip will be based on the vertical gravity: a top gravity will clip the bottom edge, a bottom gravity will clip the top - edge, and neither will clip both edges.
clip_horizontal0x08 Additional option that can be set to have the left and/or right edges of the child clipped to its container's bounds. - The clip will be based on the horizontal gravity: a left gravity will clip the right edge, a right gravity will clip the - left edge, and neither will clip both edges.
- @attr name android:indicator_gravity - */ - public static final int TreeViewList_indicator_gravity = 5; - /** -

This symbol is the offset where the {@link pl.polidea.treeview.R.attr#row_background} - attribute's value can be found in the {@link #TreeViewList} array. - - -

May be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

May be a color value, in the form of "#rgb", "#argb", -"#rrggbb", or "#aarrggbb". - @attr name android:row_background - */ - public static final int TreeViewList_row_background = 7; - /** -

This symbol is the offset where the {@link pl.polidea.treeview.R.attr#src_collapsed} - attribute's value can be found in the {@link #TreeViewList} array. - - -

May be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

May be a color value, in the form of "#rgb", "#argb", -"#rrggbb", or "#aarrggbb". - @attr name android:src_collapsed - */ - public static final int TreeViewList_src_collapsed = 2; - /** -

This symbol is the offset where the {@link pl.polidea.treeview.R.attr#src_expanded} - attribute's value can be found in the {@link #TreeViewList} array. - - -

May be a reference to another resource, in the form "@[+][package:]type:name" -or to a theme attribute in the form "?[package:][type:]name". -

May be a color value, in the form of "#rgb", "#argb", -"#rrggbb", or "#aarrggbb". - @attr name android:src_expanded - */ - public static final int TreeViewList_src_expanded = 1; - }; -} diff --git a/android-libraries/TreeViewList/proguard.cfg b/android-libraries/TreeViewList/proguard.cfg deleted file mode 100644 index b1cdf17b5..000000000 --- a/android-libraries/TreeViewList/proguard.cfg +++ /dev/null @@ -1,40 +0,0 @@ --optimizationpasses 5 --dontusemixedcaseclassnames --dontskipnonpubliclibraryclasses --dontpreverify --verbose --optimizations !code/simplification/arithmetic,!field/*,!class/merging/* - --keep public class * extends android.app.Activity --keep public class * extends android.app.Application --keep public class * extends android.app.Service --keep public class * extends android.content.BroadcastReceiver --keep public class * extends android.content.ContentProvider --keep public class * extends android.app.backup.BackupAgentHelper --keep public class * extends android.preference.Preference --keep public class com.android.vending.licensing.ILicensingService - --keepclasseswithmembernames class * { - native ; -} - --keepclasseswithmembers class * { - public (android.content.Context, android.util.AttributeSet); -} - --keepclasseswithmembers class * { - public (android.content.Context, android.util.AttributeSet, int); -} - --keepclassmembers class * extends android.app.Activity { - public void *(android.view.View); -} - --keepclassmembers enum * { - public static **[] values(); - public static ** valueOf(java.lang.String); -} - --keep class * implements android.os.Parcelable { - public static final android.os.Parcelable$Creator *; -} diff --git a/android-libraries/TreeViewList/project.properties b/android-libraries/TreeViewList/project.properties deleted file mode 100644 index 5fa344c93..000000000 --- a/android-libraries/TreeViewList/project.properties +++ /dev/null @@ -1,12 +0,0 @@ -# This file is automatically generated by Android Tools. -# Do not modify this file -- YOUR CHANGES WILL BE ERASED! -# -# This file must be checked in Version Control Systems. -# -# To customize properties used by the Ant build system use, -# "ant.properties", and override values to adapt the script to your -# project structure. - -# Project target. -target=android-15 -android.library=true diff --git a/android-libraries/TreeViewList/res/drawable-hdpi/collapsed.png b/android-libraries/TreeViewList/res/drawable-hdpi/collapsed.png deleted file mode 100644 index c1e1f3d5161c0edc790a37380da0db0b81adbe83..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 455 zcmeAS@N?(olHy`uVBq!ia0vp^av;nBBpBqPKh^;$rX+877Y2q^y~;*F9%q3^WHAE+ zw=f7ZGR&GI!N9=C>FMGaqH%uf<=tI}97Gx(?s+OE*3|KtLCma7tlQP==(Q?V#jr|7 zRfWtPo*NQ-e2(4enGJ5e7R_&@76i_YPP=@q!#$5 z{PcQe(q3Tt=8R3lq^m}UGas+p_iOFOx4U-FIN38@xcG*9@4Evg&*Kz7*Ijg;8}@kd zO}C6KY%?dX%{_bU?z87tHqB9n)UpoJ-;N#ypKbVVGH=e#*^F%;*^NnbE$J6JT z8BhIxDKn*Jtwgx%XOBIOOs*@n&g(tu^pH5ZYLWK`hTx5^QGD*RO@JY#TH+c}l9E`G zYL#4+3Zxi}3=9o*4UBaSOhXLKtqd)#42-o646O_d9=zqtLD7(#pOTqYiCe?O4cjgN PH86O(`njxgN@xNAudlK* diff --git a/android-libraries/TreeViewList/res/drawable-hdpi/expanded.png b/android-libraries/TreeViewList/res/drawable-hdpi/expanded.png deleted file mode 100644 index cec254aa7fb3e42a98f787776471023e5a827ff3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 361 zcmeAS@N?(olHy`uVBq!ia0vp^av;nBBpBqPKh^;$rX+877Y2q^y~;*F9%q3^WHAE+ zw=f7ZGR&GI0Tf*A>EaloasKXQd#*zUBF8`8yQW;h<$f@l!>W?eQ9xXrRopdql9}(U zN%p>zR|#%v2@gMd{=>BQ-yTeVDxdmr0pt4~1IdPq+R3L}nO91lEOObgO?JuD)Dwq( z$vraR-TCqt`;pnN3*HX1a!7)iEBhj zN@7W>RdP`(kYX@0Ff`OPFxE9N4KXygGPJNVHP$vTv@$SoKc8)eq9HdwB{QuOw+6FG Sm%D%(7(8A5T-G@yGywo2v48mh diff --git a/android-libraries/TreeViewList/res/drawable-hdpi/ic_launcher.png b/android-libraries/TreeViewList/res/drawable-hdpi/ic_launcher.png deleted file mode 100644 index 8074c4c571b8cd19e27f4ee5545df367420686d7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4147 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 diff --git a/android-libraries/TreeViewList/res/drawable-ldpi/collapsed.png b/android-libraries/TreeViewList/res/drawable-ldpi/collapsed.png deleted file mode 100644 index a52e846afa9e10c440191d1933470fd96bbea71c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 313 zcmeAS@N?(olHy`uVBq!ia0vp^{2Tr)5S4_<9g^BL#_q`p4Nx+E?>QA{Y7DKYd3pAap47F5l$@*R$ouk zYkX{P?OFCcbakA^G-G-^S6X=mXF2O>!H8WNH;a2FPQ0|&-|(B+=d4@jd$Pl4p1hd- z#y51zu8r$YZd-Qc>yFyrp4V^MU+0;5GB0UQUZ?XXzvUu-m>s0gUurVE`~c_-)e_f; zl9a@fRIB8oR3OD*WMF8hYhbKvU>ag*Ze?g;Wn`>vU}$Av;LDYykD?(rKP5A*61N7M T@LQ9C8W=oX{an^LB{Ts5*T`oi diff --git a/android-libraries/TreeViewList/res/drawable-ldpi/expanded.png b/android-libraries/TreeViewList/res/drawable-ldpi/expanded.png deleted file mode 100644 index d8b7ab894ede111d6565161befce37412be81ab5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 291 zcmeAS@N?(olHy`uVBq!ia0vp^{22%IkD z|M#nG=Om&1W{MME#NRf&{O?%K0s)|fswJ)wB`Jv|saDBFsX&Us$iUE0*T7iUz%<0r v+{)0x%EU<9z|hLTKvyV121P?|eoAIqC2kEd{x=o?H86O(`njxgN@xNAXi8W~ diff --git a/android-libraries/TreeViewList/res/drawable-ldpi/ic_launcher.png b/android-libraries/TreeViewList/res/drawable-ldpi/ic_launcher.png deleted file mode 100644 index 1095584ec21f71cd0afc9e0993aa2209671b590c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1723 zcmV;s21NOZP)AReP91Tc8>~sHP8V>Ys(CF=aT`Sk=;|pS}XrJPb~T1dys{sdO&0YpQBSz*~us zcN*3-J_EnE1cxrXiq*F~jZje~rkAe3vf3>;eR)3?Ox=jK*jEU7Do|T`2NqP{56w(* zBAf)rvPB_7rsfeKd0^!CaR%BHUC$tsP9m8a!i@4&TxxzagzsYHJvblx4rRUu#0Jlz zclZJwdC}7S3BvwaIMTiwb!98zRf|zoya>NudJkDGgEYs=q*HmC)>GExofw=92}s;l z_YgKLUT5`<1RBwq{f)K~I%M=gRE6d)b5BP`8{u9x0-wsG%H)w^ zRU7n9FwtlfsZSjiSB(k8~Y5+O>dyoSI477Ly?|FR?m))C!ci%BtY!2Sst8Uri#|SFX&)8{_Ou2 z9r5p3Vz9_GY#%D>%huqp_>U}K45YGy__TE!HZA@bMxX~@{;>cGYRgH~Ih*vd7EgV7h6Pg$#$lH+5=^lj{W80p{{l+;{7_t5cv3xVUy zl_BY4ht1JH*EEeRS{VwTC(QFIVu8zF&P8O$gJsMgsSO35SVvBrX`Vah$Yz2-5T>-`4DJNH;N zlSSY8-mfty+|1~*;BtTwLz_w5 z+lRv)J28~G%ouyvca(@|{2->WsPii&79&nju7ITE6hMX4AQc{|KqZN#)aAvemg3IZ zCr}Y+!r}JU&^>U1C2WyZC<=47itSYQ`?$5{VH?mtFMFFExfYTsfqK%*WzH@Onc#i` zI@a|rm-WbKk{5my{mF}H>Duc$bit&yLAgFfqo2vVbm~?FeG#0F?dSP*kxSo0Ff!o@ z(C}B;r&6pa-NY4;y~5lX8g&*MYQ>yLGd^tDWC4(sGy$Ow-*!eh%xt;>ve|J1q$*w< zh;B#cz!6l2=5bkX#nJ9PJQ`ew8t>7z$bxqf*QB=l2_UB$hK|1EIfloN-jQ=qcwChF zYAkkyp=;FwcnUB3v0=*tMYMA(Hdycpt3=UYW@Tz&Wnu`?!0;l&3aEj>)78&qol`;+0OsCOi~s-t diff --git a/android-libraries/TreeViewList/res/drawable-mdpi/expanded.png b/android-libraries/TreeViewList/res/drawable-mdpi/expanded.png deleted file mode 100644 index f7377cb30cfd739a509e8e69a10890dabc58b936..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 254 zcmeAS@N?(olHy`uVBq!ia0vp^A|T8GBp6maa=Hkln3BBRT^JZv^(q?yd7K3vk;M!Q z+`=Ht$S`Y;1W?ey)5S4F;&O6DAFF{){l{0PS`}ZL9{yaNzdzvM_Hdr_@&AAIbJgu# zw*A3pWq}Vekp<-%EN|3S6djQ1H?`T=V#8p-RLv8zKKUciEY%X%h?11Vl2ohYqEsNo zU}RuusB2)XYhW5;Xl`X_WMyQcZD43+U@*V`Oa_XE-29Zxv`Q2WW>%(_R>sB<4Mhdg QCO{1gp00i_>zopr0NjsCE&u=k diff --git a/android-libraries/TreeViewList/res/drawable-mdpi/ic_launcher.png b/android-libraries/TreeViewList/res/drawable-mdpi/ic_launcher.png deleted file mode 100644 index a07c69fa5a0f4da5d5efe96eea12a543154dbab6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2574 zcmV+p3i0)cP)Q`Og{P|8RRXpj5bgrSmEzSMfBn+{{vpNxw?;5UX;iv9sYxy_`IQHs$i<61a_iv^L>h8s-`D(`e@|IgS*Fj zNGM876Gf;3D8*1UX9a%v>yJKD*QkCwW2AirU(L{qNA)JghmGItc;(H<$!ABY&gBy1vJIEUj-b8%el*o|VkG)LqNx#TG>Jvj^jIte!!+RY z)T4j$7+PoF1AkRBf}R#^T=-q|PaK1$c<4UH)Hpq3$4WA|xtr!ZQLC=*vNE>O6E9kp+5X0eKB$6>C(lPwI@3#oY zhS_%x7e|j!$yG?ECXmh~EH~^OeuK}+sWoJse3Z3?ha3n`MM9KvA?uqpEnBg4Q46)7 zM$p%a$@l;+O}vfvx%XjH`}a{(-HHth9!JaUwV0*VqGR48^gWNYN<&~7x)y$e!X>e` zZ5!6KZoxbKuV9XUDI%#M1~IVh?pNSdeb~6@$y`v|yk=XK+fHxnDqnUK4&=QRNyIVf zYbDM*cI>~qIy*a7=z7uqkw@agd(<=y-Q7L!ty_23SGdXmahO<;N=wB+j;lNm%=OHC zy zU|>La6h%92y4IPufI$9>Xu!@y`TaNgtg&41@PwMwBdmSm7)xAWDLoqjZ==P2#*k7! z3o1)cVSI3KP_!?d8G^Lg0FtLXC~JYdxi|c%h~lXEixY=%VSFF@!*3&&9>(Rb|iK54Cx5;s~PY5iaV1het%w`dgQFBAJ;aFK zImQC}(|QaCFYUm1JVfzSc)ebv=)ObI)0jwJb``}Zj9J0n0Xgn*Zc(rFM9$xh_makZbm-at_v5^SW zM1y1SW@%+FuIy*WR)i3A2N_q;(YO`O!A|Ts^%z}9ZepCj3ytlw#x%N_fNrKKtPh`< z|1{UqF`4LxHaCQ79+E=uUXCOZ35jAMRz%R%0(P!0FMv=sk>Nr8%+OzY^c-M9@+fz=G`qa@v4sF5u-2289-#$**LWnyNNDwDf1( zkUiMnw|y$tn>pQP=Vn!#|17L^5AGrjtBkN$D@v)Z7LXc5EFhLB4<;7Wehh)CMqX|W zqsiZaO^benJ_hwa&V0ub$-_HUk**?g6fm9|!@kguU6*zhK)$qn-<3*kFrYPIaqR=V zUaUvk>@F_89b@tHs8R!*QKY;INJ<2_U+K6Ca3e9Gsl2{qY0%a7J?uICWgHuLfj+MB z=GkAN1&ifT#2u}B+2S#~$5jA(Qn^;H%CCmIae4AE-Dsng|Hl*Ov!z72k3ZnJs{pp| z+pW`DDueC#mEWOf=ucJ!dTL}hzOeiS-i?m2E;`EKz4<&Lu~NnW?peqVU^@<+T3KKu z{yrI%Qy-Z%HEvLUz}n^~m?7x`xuCtNR#L2En!T>dQtIKdS#V-Hzt3RtwTeYtmQ&dR z6qXZvac*oc@BUYEH%@Ylv_1&tSjkbzzU6*h1(3^C`;1z;g_SmOtclS?KWk2VYE zM*oS<=C483XckW?GN|1jfh3Ro(h - diff --git a/android-libraries/TreeViewList/res/drawable/list_selector_background.xml b/android-libraries/TreeViewList/res/drawable/list_selector_background.xml deleted file mode 100644 index 2b21b0c1c..000000000 --- a/android-libraries/TreeViewList/res/drawable/list_selector_background.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/android-libraries/TreeViewList/res/drawable/list_selector_background_disabled.9.png b/android-libraries/TreeViewList/res/drawable/list_selector_background_disabled.9.png deleted file mode 100644 index bf970b0509b81f2d7237d865e350e88787b16df2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1252 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 T|JePN_htX$mA&s@dH33XGOeYN diff --git a/android-libraries/TreeViewList/res/drawable/list_selector_background_longpress.9.png b/android-libraries/TreeViewList/res/drawable/list_selector_background_longpress.9.png deleted file mode 100644 index 5cbb251a7dbf1e7186a9aae78a786b6d667de6ca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3017 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 LNkvXXu0mjflqZiH diff --git a/android-libraries/TreeViewList/res/drawable/list_selector_background_pressed.9.png b/android-libraries/TreeViewList/res/drawable/list_selector_background_pressed.9.png deleted file mode 100644 index 02b4e9a536fedd342ecef1d0153ef97a3fe69452..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11006 zcmds-yNg{_7{&J;lNmE+EFwbC#@gD>#>j+ZP=kmFVk1_TiYWvOL937^Vkd&>ECl}p zOItxi{3C3{CK%&f_c~|)-0Oa`&*R>?8HhWav%bgr9_yTWgqgYZ`i*M``_JsBln#!r zAHI?C1znHt=KGHyKl^)z-S=L(c9@p>clU>Hzs!*fA6$R?qm-U_O4lNN_4VZ(+`D=7 z+SR?^E?!D6UjF6h&tFaHxpZ`R<<0lcFK#}6``5*Cxy-DGdlrjDHzdzmJlshsb%MV8 zaIxIUqZZp3w{DLuJWsuo<9xk!C#7?GVh0!Uo6Od^$2NF=2mm)|(Ul+!T%*r}e^UDE zL0`}bdio%xC$p&C^E0}zxX^7%iQ!M73&0k-J<;R--zoihuP1eaB<9k^{7I-!(bi!} zM1bOY&iz)ORxB>=KEgcK=yC6U4R(U`W+Y~RuO|MpSU#c%#IPM@&pB~fM5q=!Vxun~ zU7estz7Mgma3^2*%3=$3BKFbg`;Z{T)e|wt)`}VnVGavoVHZNoQJwJVDu2#lX>nOx zwb;J6_K=S-&*da zkgL!H!-ABhU=G4}ls$CR6CvV6-|Lj)z!P$j%UA`G6zaG?$ELCw+Fh}os8k>cq2!F$+e-+ePl;y}ppEv^}o<;<Ow-4#+&mGC|*2 z#t%&$y%Dy$IA^@;NiKaNuGzPLLo7luO<9UONZgTJMCZ88({}Vcw)#bmVqDJ4c6~#U zAfjTNXv2?j@jXU;L^vRI^0}yq9O7P6V)b*#Np5>H8hD-jXD z`0?ynK96~Ch_622S#HQoaANj6K@&}y>9GaIa?NJ*gVW!KG~Bf?SAfmUmQhe3p@qT?RG5IkNGwTj;_XP1}M*q&Y(Te}Kv%g5`xe_`NrM zXO5%n=(`YdjqbyOMD{|2Aw)TBab1x7xrZ5!(U$MmNbhk$Dx?w1J1Q52;ExPlNvVfU z3z-e}%+dR_Aj)a#f|Nr5=rL-C5E05_J2G>qz7d}8yAR;{C_z_v0IDSO(GjV-E xG;R%^5gSDrymS20H+O#eLeJvp>W#ziUw-$qe*spuA{hVx diff --git a/android-libraries/TreeViewList/res/drawable/list_selector_background_transition.xml b/android-libraries/TreeViewList/res/drawable/list_selector_background_transition.xml deleted file mode 100644 index 0dec1335d..000000000 --- a/android-libraries/TreeViewList/res/drawable/list_selector_background_transition.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - diff --git a/android-libraries/TreeViewList/res/layout/tree_list_item_wrapper.xml b/android-libraries/TreeViewList/res/layout/tree_list_item_wrapper.xml deleted file mode 100644 index 9512a0c80..000000000 --- a/android-libraries/TreeViewList/res/layout/tree_list_item_wrapper.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - diff --git a/android-libraries/TreeViewList/res/values/attrs.xml b/android-libraries/TreeViewList/res/values/attrs.xml deleted file mode 100644 index 30060a4c7..000000000 --- a/android-libraries/TreeViewList/res/values/attrs.xml +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/android-libraries/TreeViewList/res/values/styles.xml b/android-libraries/TreeViewList/res/values/styles.xml deleted file mode 100644 index 005c60078..000000000 --- a/android-libraries/TreeViewList/res/values/styles.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - diff --git a/android-libraries/TreeViewList/src/pl/polidea/treeview/AbstractTreeViewAdapter.java b/android-libraries/TreeViewList/src/pl/polidea/treeview/AbstractTreeViewAdapter.java deleted file mode 100644 index 7f2b366ad..000000000 --- a/android-libraries/TreeViewList/src/pl/polidea/treeview/AbstractTreeViewAdapter.java +++ /dev/null @@ -1,315 +0,0 @@ -package pl.polidea.treeview; - -import android.app.Activity; -import android.content.Context; -import android.database.DataSetObserver; -import android.graphics.drawable.Drawable; -import android.view.LayoutInflater; -import android.view.View; -import android.view.View.OnClickListener; -import android.view.ViewGroup; -import android.widget.BaseAdapter; -import android.widget.FrameLayout; -import android.widget.FrameLayout.LayoutParams; -import android.widget.ImageView; -import android.widget.ImageView.ScaleType; -import android.widget.LinearLayout; -import android.widget.ListAdapter; - -/** - * Adapter used to feed the table view. - * - * @param - * class for ID of the tree - */ -public abstract class AbstractTreeViewAdapter extends BaseAdapter implements - ListAdapter { - private final TreeStateManager treeStateManager; - private final int numberOfLevels; - private final LayoutInflater layoutInflater; - - private int indentWidth = 0; - private int indicatorGravity = 0; - private Drawable collapsedDrawable; - private Drawable expandedDrawable; - private Drawable indicatorBackgroundDrawable; - private Drawable rowBackgroundDrawable; - - private final OnClickListener indicatorClickListener = new OnClickListener() { - @Override - public void onClick(final View v) { - @SuppressWarnings("unchecked") - final T id = (T) v.getTag(); - expandCollapse(id); - } - }; - - private boolean collapsible; - private final Activity activity; - - public Activity getActivity() { - return activity; - } - - protected TreeStateManager getManager() { - return treeStateManager; - } - - protected void expandCollapse(final T id) { - final TreeNodeInfo info = treeStateManager.getNodeInfo(id); - if (!info.isWithChildren()) { - // ignore - no default action - return; - } - if (info.isExpanded()) { - treeStateManager.collapseChildren(id); - } else { - treeStateManager.expandDirectChildren(id); - } - } - - private void calculateIndentWidth() { - if (expandedDrawable != null) { - indentWidth = Math.max(getIndentWidth(), - expandedDrawable.getIntrinsicWidth()); - } - if (collapsedDrawable != null) { - indentWidth = Math.max(getIndentWidth(), - collapsedDrawable.getIntrinsicWidth()); - } - } - - public AbstractTreeViewAdapter(final Activity activity, - final TreeStateManager treeStateManager, final int numberOfLevels) { - this.activity = activity; - this.treeStateManager = treeStateManager; - this.layoutInflater = (LayoutInflater) activity - .getSystemService(Context.LAYOUT_INFLATER_SERVICE); - this.numberOfLevels = numberOfLevels; - this.collapsedDrawable = null; - this.expandedDrawable = null; - this.rowBackgroundDrawable = null; - this.indicatorBackgroundDrawable = null; - } - - @Override - public void registerDataSetObserver(final DataSetObserver observer) { - treeStateManager.registerDataSetObserver(observer); - } - - @Override - public void unregisterDataSetObserver(final DataSetObserver observer) { - treeStateManager.unregisterDataSetObserver(observer); - } - - @Override - public int getCount() { - return treeStateManager.getVisibleCount(); - } - - @Override - public Object getItem(final int position) { - return getItemId(position); - } - - public T getTreeId(final int position) { - return treeStateManager.getVisibleList().get(position); - } - - public TreeNodeInfo getTreeNodeInfo(final int position) { - return treeStateManager.getNodeInfo(getTreeId(position)); - } - - @Override - public boolean hasStableIds() { // NOPMD - return true; - } - - @Override - public int getItemViewType(final int position) { - return getTreeNodeInfo(position).getLevel(); - } - - @Override - public int getViewTypeCount() { - return numberOfLevels; - } - - @Override - public boolean isEmpty() { - return getCount() == 0; - } - - @Override - public boolean areAllItemsEnabled() { // NOPMD - return true; - } - - @Override - public boolean isEnabled(final int position) { // NOPMD - return true; - } - - protected int getTreeListItemWrapperId() { - return R.layout.tree_list_item_wrapper; - } - - @Override - public final View getView(final int position, final View convertView, - final ViewGroup parent) { - final TreeNodeInfo nodeInfo = getTreeNodeInfo(position); - if (convertView == null) { - final LinearLayout layout = (LinearLayout) layoutInflater.inflate( - getTreeListItemWrapperId(), null); - return populateTreeItem(layout, getNewChildView(nodeInfo), - nodeInfo, true); - } else { - final LinearLayout linear = (LinearLayout) convertView; - final FrameLayout frameLayout = (FrameLayout) linear - .findViewById(R.id.treeview_list_item_frame); - final View childView = frameLayout.getChildAt(0); - updateView(childView, nodeInfo); - return populateTreeItem(linear, childView, nodeInfo, false); - } - } - - /** - * Called when new view is to be created. - * - * @param treeNodeInfo - * node info - * @return view that should be displayed as tree content - */ - public abstract View getNewChildView(TreeNodeInfo treeNodeInfo); - - /** - * Called when new view is going to be reused. You should update the view - * and fill it in with the data required to display the new information. You - * can also create a new view, which will mean that the old view will not be - * reused. - * - * @param view - * view that should be updated with the new values - * @param treeNodeInfo - * node info used to populate the view - * @return view to used as row indented content - */ - public abstract View updateView(View view, TreeNodeInfo treeNodeInfo); - - /** - * Retrieves background drawable for the node. - * - * @param treeNodeInfo - * node info - * @return drawable returned as background for the whole row. Might be null, - * then default background is used - */ - public Drawable getBackgroundDrawable(final TreeNodeInfo treeNodeInfo) { // NOPMD - return null; - } - - private Drawable getDrawableOrDefaultBackground(final Drawable r) { - if (r == null) { - return activity.getResources() - .getDrawable(R.drawable.list_selector_background).mutate(); - } else { - return r; - } - } - - public final LinearLayout populateTreeItem(final LinearLayout layout, - final View childView, final TreeNodeInfo nodeInfo, - final boolean newChildView) { - final Drawable individualRowDrawable = getBackgroundDrawable(nodeInfo); - layout.setBackgroundDrawable(individualRowDrawable == null ? getDrawableOrDefaultBackground(rowBackgroundDrawable) - : individualRowDrawable); - final LinearLayout.LayoutParams indicatorLayoutParams = new LinearLayout.LayoutParams( - calculateIndentation(nodeInfo), LayoutParams.FILL_PARENT); - final LinearLayout indicatorLayout = (LinearLayout) layout - .findViewById(R.id.treeview_list_item_image_layout); - indicatorLayout.setGravity(indicatorGravity); - indicatorLayout.setLayoutParams(indicatorLayoutParams); - final ImageView image = (ImageView) layout - .findViewById(R.id.treeview_list_item_image); - image.setImageDrawable(getDrawable(nodeInfo)); - image.setBackgroundDrawable(getDrawableOrDefaultBackground(indicatorBackgroundDrawable)); - image.setScaleType(ScaleType.CENTER); - image.setTag(nodeInfo.getId()); - if (nodeInfo.isWithChildren() && collapsible) { - image.setOnClickListener(indicatorClickListener); - } else { - image.setOnClickListener(null); - } - layout.setTag(nodeInfo.getId()); - final FrameLayout frameLayout = (FrameLayout) layout - .findViewById(R.id.treeview_list_item_frame); - final FrameLayout.LayoutParams childParams = new FrameLayout.LayoutParams( - LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT); - if (newChildView) { - frameLayout.addView(childView, childParams); - } - frameLayout.setTag(nodeInfo.getId()); - return layout; - } - - protected int calculateIndentation(final TreeNodeInfo nodeInfo) { - return getIndentWidth() * (nodeInfo.getLevel() + (collapsible ? 1 : 0)); - } - - private Drawable getDrawable(final TreeNodeInfo nodeInfo) { - if (!nodeInfo.isWithChildren() || !collapsible) { - return getDrawableOrDefaultBackground(indicatorBackgroundDrawable); - } - if (nodeInfo.isExpanded()) { - return expandedDrawable; - } else { - return collapsedDrawable; - } - } - - public void setIndicatorGravity(final int indicatorGravity) { - this.indicatorGravity = indicatorGravity; - } - - public void setCollapsedDrawable(final Drawable collapsedDrawable) { - this.collapsedDrawable = collapsedDrawable; - calculateIndentWidth(); - } - - public void setExpandedDrawable(final Drawable expandedDrawable) { - this.expandedDrawable = expandedDrawable; - calculateIndentWidth(); - } - - public void setIndentWidth(final int indentWidth) { - this.indentWidth = indentWidth; - calculateIndentWidth(); - } - - public void setRowBackgroundDrawable(final Drawable rowBackgroundDrawable) { - this.rowBackgroundDrawable = rowBackgroundDrawable; - } - - public void setIndicatorBackgroundDrawable( - final Drawable indicatorBackgroundDrawable) { - this.indicatorBackgroundDrawable = indicatorBackgroundDrawable; - } - - public void setCollapsible(final boolean collapsible) { - this.collapsible = collapsible; - } - - public void refresh() { - treeStateManager.refresh(); - } - - private int getIndentWidth() { - return indentWidth; - } - - @SuppressWarnings("unchecked") - public void handleItemClick(final View view, final Object id) { - expandCollapse((T) id); - } - -} diff --git a/android-libraries/TreeViewList/src/pl/polidea/treeview/InMemoryTreeNode.java b/android-libraries/TreeViewList/src/pl/polidea/treeview/InMemoryTreeNode.java deleted file mode 100644 index 6035369f9..000000000 --- a/android-libraries/TreeViewList/src/pl/polidea/treeview/InMemoryTreeNode.java +++ /dev/null @@ -1,116 +0,0 @@ -package pl.polidea.treeview; - -import java.io.Serializable; -import java.util.LinkedList; -import java.util.List; - -/** - * Node. It is package protected so that it cannot be used outside. - * - * @param - * type of the identifier used by the tree - */ -class InMemoryTreeNode implements Serializable { - private static final long serialVersionUID = 1L; - private final T id; - private final T parent; - private final int level; - private boolean visible = true; - private final List> children = new LinkedList>(); - private List childIdListCache = null; - - public InMemoryTreeNode(final T id, final T parent, final int level, - final boolean visible) { - super(); - this.id = id; - this.parent = parent; - this.level = level; - this.visible = visible; - } - - public int indexOf(final T id) { - return getChildIdList().indexOf(id); - } - - /** - * Cache is built lasily only if needed. The cache is cleaned on any - * structure change for that node!). - * - * @return list of ids of children - */ - public synchronized List getChildIdList() { - if (childIdListCache == null) { - childIdListCache = new LinkedList(); - for (final InMemoryTreeNode n : children) { - childIdListCache.add(n.getId()); - } - } - return childIdListCache; - } - - public boolean isVisible() { - return visible; - } - - public void setVisible(final boolean visible) { - this.visible = visible; - } - - public int getChildrenListSize() { - return children.size(); - } - - public synchronized InMemoryTreeNode add(final int index, final T child, - final boolean visible) { - childIdListCache = null; - // Note! top levell children are always visible (!) - final InMemoryTreeNode newNode = new InMemoryTreeNode(child, - getId(), getLevel() + 1, getId() == null ? true : visible); - children.add(index, newNode); - return newNode; - } - - /** - * Note. This method should technically return unmodifiable collection, but - * for performance reason on small devices we do not do it. - * - * @return children list - */ - public List> getChildren() { - return children; - } - - public synchronized void clearChildren() { - children.clear(); - childIdListCache = null; - } - - public synchronized void removeChild(final T child) { - final int childIndex = indexOf(child); - if (childIndex != -1) { - children.remove(childIndex); - childIdListCache = null; - } - } - - @Override - public String toString() { - return "InMemoryTreeNode [id=" + getId() + ", parent=" + getParent() - + ", level=" + getLevel() + ", visible=" + visible - + ", children=" + children + ", childIdListCache=" - + childIdListCache + "]"; - } - - T getId() { - return id; - } - - T getParent() { - return parent; - } - - int getLevel() { - return level; - } - -} \ No newline at end of file diff --git a/android-libraries/TreeViewList/src/pl/polidea/treeview/InMemoryTreeStateManager.java b/android-libraries/TreeViewList/src/pl/polidea/treeview/InMemoryTreeStateManager.java deleted file mode 100644 index bae675bf8..000000000 --- a/android-libraries/TreeViewList/src/pl/polidea/treeview/InMemoryTreeStateManager.java +++ /dev/null @@ -1,374 +0,0 @@ -package pl.polidea.treeview; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import android.database.DataSetObserver; - -/** - * In-memory manager of tree state. - * - * @param - * type of identifier - */ -public class InMemoryTreeStateManager implements TreeStateManager { - private static final long serialVersionUID = 1L; - private final Map> allNodes = new HashMap>(); - private final InMemoryTreeNode topSentinel = new InMemoryTreeNode( - null, null, -1, true); - private transient List visibleListCache = null; // lasy initialised - private transient List unmodifiableVisibleList = null; - private boolean visibleByDefault = true; - private final transient Set observers = new HashSet(); - - private synchronized void internalDataSetChanged() { - visibleListCache = null; - unmodifiableVisibleList = null; - for (final DataSetObserver observer : observers) { - observer.onChanged(); - } - } - - /** - * If true new nodes are visible by default. - * - * @param visibleByDefault - * if true, then newly added nodes are expanded by default - */ - public void setVisibleByDefault(final boolean visibleByDefault) { - this.visibleByDefault = visibleByDefault; - } - - private InMemoryTreeNode getNodeFromTreeOrThrow(final T id) { - if (id == null) { - throw new NodeNotInTreeException("(null)"); - } - final InMemoryTreeNode node = allNodes.get(id); - if (node == null) { - throw new NodeNotInTreeException(id.toString()); - } - return node; - } - - private InMemoryTreeNode getNodeFromTreeOrThrowAllowRoot(final T id) { - if (id == null) { - return topSentinel; - } - return getNodeFromTreeOrThrow(id); - } - - private void expectNodeNotInTreeYet(final T id) { - final InMemoryTreeNode node = allNodes.get(id); - if (node != null) { - throw new NodeAlreadyInTreeException(id.toString(), node.toString()); - } - } - - @Override - public synchronized TreeNodeInfo getNodeInfo(final T id) { - final InMemoryTreeNode node = getNodeFromTreeOrThrow(id); - final List> children = node.getChildren(); - boolean expanded = false; - if (!children.isEmpty() && children.get(0).isVisible()) { - expanded = true; - } - return new TreeNodeInfo(id, node.getLevel(), !children.isEmpty(), - node.isVisible(), expanded); - } - - @Override - public synchronized List getChildren(final T id) { - final InMemoryTreeNode node = getNodeFromTreeOrThrowAllowRoot(id); - return node.getChildIdList(); - } - - @Override - public synchronized T getParent(final T id) { - final InMemoryTreeNode node = getNodeFromTreeOrThrowAllowRoot(id); - return node.getParent(); - } - - private boolean getChildrenVisibility(final InMemoryTreeNode node) { - boolean visibility; - final List> children = node.getChildren(); - if (children.isEmpty()) { - visibility = visibleByDefault; - } else { - visibility = children.get(0).isVisible(); - } - return visibility; - } - - @Override - public synchronized void addBeforeChild(final T parent, final T newChild, - final T beforeChild) { - expectNodeNotInTreeYet(newChild); - final InMemoryTreeNode node = getNodeFromTreeOrThrowAllowRoot(parent); - final boolean visibility = getChildrenVisibility(node); - // top nodes are always expanded. - if (beforeChild == null) { - final InMemoryTreeNode added = node.add(0, newChild, visibility); - allNodes.put(newChild, added); - } else { - final int index = node.indexOf(beforeChild); - final InMemoryTreeNode added = node.add(index == -1 ? 0 : index, - newChild, visibility); - allNodes.put(newChild, added); - } - if (visibility) { - internalDataSetChanged(); - } - } - - @Override - public synchronized void addAfterChild(final T parent, final T newChild, - final T afterChild) { - expectNodeNotInTreeYet(newChild); - final InMemoryTreeNode node = getNodeFromTreeOrThrowAllowRoot(parent); - final boolean visibility = getChildrenVisibility(node); - if (afterChild == null) { - final InMemoryTreeNode added = node.add( - node.getChildrenListSize(), newChild, visibility); - allNodes.put(newChild, added); - } else { - final int index = node.indexOf(afterChild); - final InMemoryTreeNode added = node.add( - index == -1 ? node.getChildrenListSize() : index, newChild, - visibility); - allNodes.put(newChild, added); - } - if (visibility) { - internalDataSetChanged(); - } - } - - @Override - public synchronized void removeNodeRecursively(final T id) { - final InMemoryTreeNode node = getNodeFromTreeOrThrowAllowRoot(id); - final boolean visibleNodeChanged = removeNodeRecursively(node); - final T parent = node.getParent(); - final InMemoryTreeNode parentNode = getNodeFromTreeOrThrowAllowRoot(parent); - parentNode.removeChild(id); - if (visibleNodeChanged) { - internalDataSetChanged(); - } - } - - private boolean removeNodeRecursively(final InMemoryTreeNode node) { - boolean visibleNodeChanged = false; - for (final InMemoryTreeNode child : node.getChildren()) { - if (removeNodeRecursively(child)) { - visibleNodeChanged = true; - } - } - node.clearChildren(); - if (node.getId() != null) { - allNodes.remove(node.getId()); - if (node.isVisible()) { - visibleNodeChanged = true; - } - } - return visibleNodeChanged; - } - - private void setChildrenVisibility(final InMemoryTreeNode node, - final boolean visible, final boolean recursive) { - for (final InMemoryTreeNode child : node.getChildren()) { - child.setVisible(visible); - if (recursive) { - setChildrenVisibility(child, visible, true); - } - } - } - - @Override - public synchronized void expandDirectChildren(final T id) { - final InMemoryTreeNode node = getNodeFromTreeOrThrowAllowRoot(id); - setChildrenVisibility(node, true, false); - internalDataSetChanged(); - } - - @Override - public synchronized void expandEverythingBelow(final T id) { - final InMemoryTreeNode node = getNodeFromTreeOrThrowAllowRoot(id); - setChildrenVisibility(node, true, true); - internalDataSetChanged(); - } - - @Override - public synchronized void collapseChildren(final T id) { - final InMemoryTreeNode node = getNodeFromTreeOrThrowAllowRoot(id); - if (node == topSentinel) { - for (final InMemoryTreeNode n : topSentinel.getChildren()) { - setChildrenVisibility(n, false, true); - } - } else { - setChildrenVisibility(node, false, true); - } - internalDataSetChanged(); - } - - @Override - public synchronized T getNextSibling(final T id) { - final T parent = getParent(id); - final InMemoryTreeNode parentNode = getNodeFromTreeOrThrowAllowRoot(parent); - boolean returnNext = false; - for (final InMemoryTreeNode child : parentNode.getChildren()) { - if (returnNext) { - return child.getId(); - } - if (child.getId().equals(id)) { - returnNext = true; - } - } - return null; - } - - @Override - public synchronized T getPreviousSibling(final T id) { - final T parent = getParent(id); - final InMemoryTreeNode parentNode = getNodeFromTreeOrThrowAllowRoot(parent); - final T previousSibling = null; - for (final InMemoryTreeNode child : parentNode.getChildren()) { - if (child.getId().equals(id)) { - return previousSibling; - } - } - return null; - } - - @Override - public synchronized boolean isInTree(final T id) { - return allNodes.containsKey(id); - } - - @Override - public synchronized int getVisibleCount() { - return getVisibleList().size(); - } - - @Override - public synchronized List getVisibleList() { - T currentId = null; - if (visibleListCache == null) { - visibleListCache = new ArrayList(allNodes.size()); - do { - currentId = getNextVisible(currentId); - if (currentId == null) { - break; - } else { - visibleListCache.add(currentId); - } - } while (true); - } - if (unmodifiableVisibleList == null) { - unmodifiableVisibleList = Collections - .unmodifiableList(visibleListCache); - } - return unmodifiableVisibleList; - } - - public synchronized T getNextVisible(final T id) { - final InMemoryTreeNode node = getNodeFromTreeOrThrowAllowRoot(id); - if (!node.isVisible()) { - return null; - } - final List> children = node.getChildren(); - if (!children.isEmpty()) { - final InMemoryTreeNode firstChild = children.get(0); - if (firstChild.isVisible()) { - return firstChild.getId(); - } - } - final T sibl = getNextSibling(id); - if (sibl != null) { - return sibl; - } - T parent = node.getParent(); - do { - if (parent == null) { - return null; - } - final T parentSibling = getNextSibling(parent); - if (parentSibling != null) { - return parentSibling; - } - parent = getNodeFromTreeOrThrow(parent).getParent(); - } while (true); - } - - @Override - public synchronized void registerDataSetObserver( - final DataSetObserver observer) { - observers.add(observer); - } - - @Override - public synchronized void unregisterDataSetObserver( - final DataSetObserver observer) { - observers.remove(observer); - } - - @Override - public int getLevel(final T id) { - return getNodeFromTreeOrThrow(id).getLevel(); - } - - @Override - public Integer[] getHierarchyDescription(final T id) { - final int level = getLevel(id); - final Integer[] hierarchy = new Integer[level + 1]; - int currentLevel = level; - T currentId = id; - T parent = getParent(currentId); - while (currentLevel >= 0) { - hierarchy[currentLevel--] = getChildren(parent).indexOf(currentId); - currentId = parent; - parent = getParent(parent); - } - return hierarchy; - } - - private void appendToSb(final StringBuilder sb, final T id) { - if (id != null) { - final TreeNodeInfo node = getNodeInfo(id); - final int indent = node.getLevel() * 4; - final char[] indentString = new char[indent]; - Arrays.fill(indentString, ' '); - sb.append(indentString); - sb.append(node.toString()); - sb.append(Arrays.asList(getHierarchyDescription(id)).toString()); - sb.append("\n"); - } - final List children = getChildren(id); - for (final T child : children) { - appendToSb(sb, child); - } - } - - @Override - public synchronized String toString() { - final StringBuilder sb = new StringBuilder(); - appendToSb(sb, null); - return sb.toString(); - } - - @Override - public synchronized void clear() { - allNodes.clear(); - topSentinel.clearChildren(); - internalDataSetChanged(); - } - - @Override - public void refresh() { - internalDataSetChanged(); - } - -} diff --git a/android-libraries/TreeViewList/src/pl/polidea/treeview/NodeAlreadyInTreeException.java b/android-libraries/TreeViewList/src/pl/polidea/treeview/NodeAlreadyInTreeException.java deleted file mode 100644 index 680d0266d..000000000 --- a/android-libraries/TreeViewList/src/pl/polidea/treeview/NodeAlreadyInTreeException.java +++ /dev/null @@ -1,14 +0,0 @@ -package pl.polidea.treeview; - -/** - * The node being added is already in the tree. - * - */ -public class NodeAlreadyInTreeException extends RuntimeException { - private static final long serialVersionUID = 1L; - - public NodeAlreadyInTreeException(final String id, final String oldNode) { - super("The node has already been added to the tree: " + id + ". Old node is:" + oldNode); - } - -} diff --git a/android-libraries/TreeViewList/src/pl/polidea/treeview/NodeNotInTreeException.java b/android-libraries/TreeViewList/src/pl/polidea/treeview/NodeNotInTreeException.java deleted file mode 100644 index f20450e1d..000000000 --- a/android-libraries/TreeViewList/src/pl/polidea/treeview/NodeNotInTreeException.java +++ /dev/null @@ -1,15 +0,0 @@ -package pl.polidea.treeview; - -/** - * This exception is thrown when the tree does not contain node requested. - * - */ -public class NodeNotInTreeException extends RuntimeException { - - private static final long serialVersionUID = 1L; - - public NodeNotInTreeException(final String id) { - super("The tree does not contain the node specified: " + id); - } - -} diff --git a/android-libraries/TreeViewList/src/pl/polidea/treeview/TreeBuilder.java b/android-libraries/TreeViewList/src/pl/polidea/treeview/TreeBuilder.java deleted file mode 100644 index 13b499c47..000000000 --- a/android-libraries/TreeViewList/src/pl/polidea/treeview/TreeBuilder.java +++ /dev/null @@ -1,126 +0,0 @@ -package pl.polidea.treeview; - -import android.util.Log; - -/** - * Allows to build tree easily in sequential mode (you have to know levels of - * all the tree elements upfront). You should rather use this class rather than - * manager if you build initial tree from some external data source. - * - * @param - */ -public class TreeBuilder { - private static final String TAG = TreeBuilder.class.getSimpleName(); - - private final TreeStateManager manager; - - private T lastAddedId = null; - private int lastLevel = -1; - - public TreeBuilder(final TreeStateManager manager) { - this.manager = manager; - } - - public void clear() { - manager.clear(); - } - - /** - * Adds new relation to existing tree. Child is set as the last child of the - * parent node. Parent has to already exist in the tree, child cannot yet - * exist. This method is mostly useful in case you add entries layer by - * layer - i.e. first top level entries, then children for all parents, then - * grand-children and so on. - * - * @param parent - * parent id - * @param child - * child id - */ - public synchronized void addRelation(final T parent, final T child) { - Log.d(TAG, "Adding relation parent:" + parent + " -> child: " + child); - manager.addAfterChild(parent, child, null); - lastAddedId = child; - lastLevel = manager.getLevel(child); - } - - /** - * Adds sequentially new node. Using this method is the simplest way of - * building tree - if you have all the elements in the sequence as they - * should be displayed in fully-expanded tree. You can combine it with add - * relation - for example you can add information about few levels using - * {@link addRelation} and then after the right level is added as parent, - * you can continue adding them using sequential operation. - * - * @param id - * id of the node - * @param level - * its level - */ - public synchronized void sequentiallyAddNextNode(final T id, final int level) { - Log.d(TAG, "Adding sequentiall node " + id + " at level " + level); - if (lastAddedId == null) { - addNodeToParentOneLevelDown(null, id, level); - } else { - if (level <= lastLevel) { - final T parent = findParentAtLevel(lastAddedId, level - 1); - addNodeToParentOneLevelDown(parent, id, level); - } else { - addNodeToParentOneLevelDown(lastAddedId, id, level); - } - } - } - - /** - * Find parent of the node at the level specified. - * - * @param node - * node from which we start - * @param levelToFind - * level which we are looking for - * @return the node found (null if it is topmost node). - */ - private T findParentAtLevel(final T node, final int levelToFind) { - T parent = manager.getParent(node); - while (parent != null) { - if (manager.getLevel(parent) == levelToFind) { - break; - } - parent = manager.getParent(parent); - } - return parent; - } - - /** - * Adds note to parent at the level specified. But it verifies that the - * level is one level down than the parent! - * - * @param parent - * parent parent - * @param id - * new node id - * @param level - * should always be parent's level + 1 - */ - private void addNodeToParentOneLevelDown(final T parent, final T id, - final int level) { - if (parent == null && level != 0) { - throw new TreeConfigurationException("Trying to add new id " + id - + " to top level with level != 0 (" + level + ")"); - } - if (parent != null && manager.getLevel(parent) != level - 1) { - throw new TreeConfigurationException("Trying to add new id " + id - + " <" + level + "> to " + parent + " <" - + manager.getLevel(parent) - + ">. The difference in levels up is bigger than 1."); - } - manager.addAfterChild(parent, id, null); - setLastAdded(id, level); - } - - private void setLastAdded(final T id, final int level) { - lastAddedId = id; - lastLevel = level; - } - -} diff --git a/android-libraries/TreeViewList/src/pl/polidea/treeview/TreeConfigurationException.java b/android-libraries/TreeViewList/src/pl/polidea/treeview/TreeConfigurationException.java deleted file mode 100644 index 1fa72e04c..000000000 --- a/android-libraries/TreeViewList/src/pl/polidea/treeview/TreeConfigurationException.java +++ /dev/null @@ -1,15 +0,0 @@ -package pl.polidea.treeview; - -/** - * Exception thrown when there is a problem with configuring tree. - * - */ -public class TreeConfigurationException extends RuntimeException { - - private static final long serialVersionUID = 1L; - - public TreeConfigurationException(final String detailMessage) { - super(detailMessage); - } - -} diff --git a/android-libraries/TreeViewList/src/pl/polidea/treeview/TreeNodeInfo.java b/android-libraries/TreeViewList/src/pl/polidea/treeview/TreeNodeInfo.java deleted file mode 100644 index 32d18dd44..000000000 --- a/android-libraries/TreeViewList/src/pl/polidea/treeview/TreeNodeInfo.java +++ /dev/null @@ -1,69 +0,0 @@ -package pl.polidea.treeview; - -/** - * Information about the node. - * - * @param - * type of the id for the tree - */ -public class TreeNodeInfo { - private final T id; - private final int level; - private final boolean withChildren; - private final boolean visible; - private final boolean expanded; - - /** - * Creates the node information. - * - * @param id - * id of the node - * @param level - * level of the node - * @param withChildren - * whether the node has children. - * @param visible - * whether the tree node is visible. - * @param expanded - * whether the tree node is expanded - * - */ - public TreeNodeInfo(final T id, final int level, - final boolean withChildren, final boolean visible, - final boolean expanded) { - super(); - this.id = id; - this.level = level; - this.withChildren = withChildren; - this.visible = visible; - this.expanded = expanded; - } - - public T getId() { - return id; - } - - public boolean isWithChildren() { - return withChildren; - } - - public boolean isVisible() { - return visible; - } - - public boolean isExpanded() { - return expanded; - } - - public int getLevel() { - return level; - } - - @Override - public String toString() { - return "TreeNodeInfo [id=" + id + ", level=" + level - + ", withChildren=" + withChildren + ", visible=" + visible - + ", expanded=" + expanded + "]"; - } - -} \ No newline at end of file diff --git a/android-libraries/TreeViewList/src/pl/polidea/treeview/TreeStateManager.java b/android-libraries/TreeViewList/src/pl/polidea/treeview/TreeStateManager.java deleted file mode 100644 index 781b70e58..000000000 --- a/android-libraries/TreeViewList/src/pl/polidea/treeview/TreeStateManager.java +++ /dev/null @@ -1,193 +0,0 @@ -package pl.polidea.treeview; - -import java.io.Serializable; -import java.util.List; - -import android.database.DataSetObserver; - -/** - * Manages information about state of the tree. It only keeps information about - * tree elements, not the elements themselves. - * - * @param - * type of the identifier for nodes in the tree - */ -public interface TreeStateManager extends Serializable { - - /** - * Returns array of integers showing the location of the node in hierarchy. - * It corresponds to heading numbering. {0,0,0} in 3 level node is the first - * node {0,0,1} is second leaf (assuming that there are two leaves in first - * subnode of the first node). - * - * @param id - * id of the node - * @return textual description of the hierarchy in tree for the node. - */ - Integer[] getHierarchyDescription(T id); - - /** - * Returns level of the node. - * - * @param id - * id of the node - * @return level in the tree - */ - int getLevel(T id); - - /** - * Returns information about the node. - * - * @param id - * node id - * @return node info - */ - TreeNodeInfo getNodeInfo(T id); - - /** - * Returns children of the node. - * - * @param id - * id of the node or null if asking for top nodes - * @return children of the node - */ - List getChildren(T id); - - /** - * Returns parent of the node. - * - * @param id - * id of the node - * @return parent id or null if no parent - */ - T getParent(T id); - - /** - * Adds the node before child or at the beginning. - * - * @param parent - * id of the parent node. If null - adds at the top level - * @param newChild - * new child to add if null - adds at the beginning. - * @param beforeChild - * child before which to add the new child - */ - void addBeforeChild(T parent, T newChild, T beforeChild); - - /** - * Adds the node after child or at the end. - * - * @param parent - * id of the parent node. If null - adds at the top level. - * @param newChild - * new child to add. If null - adds at the end. - * @param afterChild - * child after which to add the new child - */ - void addAfterChild(T parent, T newChild, T afterChild); - - /** - * Removes the node and all children from the tree. - * - * @param id - * id of the node to remove or null if all nodes are to be - * removed. - */ - void removeNodeRecursively(T id); - - /** - * Expands all children of the node. - * - * @param id - * node which children should be expanded. cannot be null (top - * nodes are always expanded!). - */ - void expandDirectChildren(T id); - - /** - * Expands everything below the node specified. Might be null - then expands - * all. - * - * @param id - * node which children should be expanded or null if all nodes - * are to be expanded. - */ - void expandEverythingBelow(T id); - - /** - * Collapse children. - * - * @param id - * id collapses everything below node specified. If null, - * collapses everything but top-level nodes. - */ - void collapseChildren(T id); - - /** - * Returns next sibling of the node (or null if no further sibling). - * - * @param id - * node id - * @return the sibling (or null if no next) - */ - T getNextSibling(T id); - - /** - * Returns previous sibling of the node (or null if no previous sibling). - * - * @param id - * node id - * @return the sibling (or null if no previous) - */ - T getPreviousSibling(T id); - - /** - * Checks if given node is already in tree. - * - * @param id - * id of the node - * @return true if node is already in tree. - */ - boolean isInTree(T id); - - /** - * Count visible elements. - * - * @return number of currently visible elements. - */ - int getVisibleCount(); - - /** - * Returns visible node list. - * - * @return return the list of all visible nodes in the right sequence - */ - List getVisibleList(); - - /** - * Registers observers with the manager. - * - * @param observer - * observer - */ - void registerDataSetObserver(final DataSetObserver observer); - - /** - * Unregisters observers with the manager. - * - * @param observer - * observer - */ - void unregisterDataSetObserver(final DataSetObserver observer); - - /** - * Cleans tree stored in manager. After this operation the tree is empty. - * - */ - void clear(); - - /** - * Refreshes views connected to the manager. - */ - void refresh(); -} diff --git a/android-libraries/TreeViewList/src/pl/polidea/treeview/TreeViewList.java b/android-libraries/TreeViewList/src/pl/polidea/treeview/TreeViewList.java deleted file mode 100644 index fb48ab5c9..000000000 --- a/android-libraries/TreeViewList/src/pl/polidea/treeview/TreeViewList.java +++ /dev/null @@ -1,198 +0,0 @@ -package pl.polidea.treeview; - -import android.content.Context; -import android.content.res.TypedArray; -import android.graphics.drawable.Drawable; -import android.util.AttributeSet; -import android.view.Gravity; -import android.view.View; -import android.widget.AdapterView; -import android.widget.ListAdapter; -import android.widget.ListView; - -/** - * Tree view, expandable multi-level. - * - *

- * attr ref pl.polidea.treeview.R.styleable#TreeViewList_collapsible
- * attr ref pl.polidea.treeview.R.styleable#TreeViewList_src_expanded
- * attr ref pl.polidea.treeview.R.styleable#TreeViewList_src_collapsed
- * attr ref pl.polidea.treeview.R.styleable#TreeViewList_indent_width
- * attr ref pl.polidea.treeview.R.styleable#TreeViewList_handle_trackball_press
- * attr ref pl.polidea.treeview.R.styleable#TreeViewList_indicator_gravity
- * attr ref pl.polidea.treeview.R.styleable#TreeViewList_indicator_background
- * attr ref pl.polidea.treeview.R.styleable#TreeViewList_row_background
- * 
- */ -public class TreeViewList extends ListView { - private static final int DEFAULT_COLLAPSED_RESOURCE = R.drawable.collapsed; - private static final int DEFAULT_EXPANDED_RESOURCE = R.drawable.expanded; - private static final int DEFAULT_INDENT = 0; - private static final int DEFAULT_GRAVITY = Gravity.LEFT - | Gravity.CENTER_VERTICAL; - private Drawable expandedDrawable; - private Drawable collapsedDrawable; - private Drawable rowBackgroundDrawable; - private Drawable indicatorBackgroundDrawable; - private int indentWidth = 0; - private int indicatorGravity = 0; - private AbstractTreeViewAdapter< ? > treeAdapter; - private boolean collapsible; - private boolean handleTrackballPress; - - public TreeViewList(final Context context, final AttributeSet attrs) { - this(context, attrs, R.style.treeViewListStyle); - } - - public TreeViewList(final Context context) { - this(context, null); - } - - public TreeViewList(final Context context, final AttributeSet attrs, - final int defStyle) { - super(context, attrs, defStyle); - parseAttributes(context, attrs); - } - - private void parseAttributes(final Context context, final AttributeSet attrs) { - final TypedArray a = context.obtainStyledAttributes(attrs, - R.styleable.TreeViewList); - expandedDrawable = a.getDrawable(R.styleable.TreeViewList_src_expanded); - if (expandedDrawable == null) { - expandedDrawable = context.getResources().getDrawable( - DEFAULT_EXPANDED_RESOURCE); - } - collapsedDrawable = a - .getDrawable(R.styleable.TreeViewList_src_collapsed); - if (collapsedDrawable == null) { - collapsedDrawable = context.getResources().getDrawable( - DEFAULT_COLLAPSED_RESOURCE); - } - indentWidth = a.getDimensionPixelSize( - R.styleable.TreeViewList_indent_width, DEFAULT_INDENT); - indicatorGravity = a.getInteger( - R.styleable.TreeViewList_indicator_gravity, DEFAULT_GRAVITY); - indicatorBackgroundDrawable = a - .getDrawable(R.styleable.TreeViewList_indicator_background); - rowBackgroundDrawable = a - .getDrawable(R.styleable.TreeViewList_row_background); - collapsible = a.getBoolean(R.styleable.TreeViewList_collapsible, true); - handleTrackballPress = a.getBoolean( - R.styleable.TreeViewList_handle_trackball_press, true); - } - - @Override - public void setAdapter(final ListAdapter adapter) { - if (!(adapter instanceof AbstractTreeViewAdapter)) { - throw new TreeConfigurationException( - "The adapter is not of TreeViewAdapter type"); - } - treeAdapter = (AbstractTreeViewAdapter< ? >) adapter; - syncAdapter(); - super.setAdapter(treeAdapter); - } - - private void syncAdapter() { - treeAdapter.setCollapsedDrawable(collapsedDrawable); - treeAdapter.setExpandedDrawable(expandedDrawable); - treeAdapter.setIndicatorGravity(indicatorGravity); - treeAdapter.setIndentWidth(indentWidth); - treeAdapter.setIndicatorBackgroundDrawable(indicatorBackgroundDrawable); - treeAdapter.setRowBackgroundDrawable(rowBackgroundDrawable); - treeAdapter.setCollapsible(collapsible); - if (handleTrackballPress) { - setOnItemClickListener(new OnItemClickListener() { - @Override - public void onItemClick(final AdapterView< ? > parent, - final View view, final int position, final long id) { - treeAdapter.handleItemClick(view, view.getTag()); - } - }); - } else { - setOnClickListener(null); - } - - } - - public void setExpandedDrawable(final Drawable expandedDrawable) { - this.expandedDrawable = expandedDrawable; - syncAdapter(); - treeAdapter.refresh(); - } - - public void setCollapsedDrawable(final Drawable collapsedDrawable) { - this.collapsedDrawable = collapsedDrawable; - syncAdapter(); - treeAdapter.refresh(); - } - - public void setRowBackgroundDrawable(final Drawable rowBackgroundDrawable) { - this.rowBackgroundDrawable = rowBackgroundDrawable; - syncAdapter(); - treeAdapter.refresh(); - } - - public void setIndicatorBackgroundDrawable( - final Drawable indicatorBackgroundDrawable) { - this.indicatorBackgroundDrawable = indicatorBackgroundDrawable; - syncAdapter(); - treeAdapter.refresh(); - } - - public void setIndentWidth(final int indentWidth) { - this.indentWidth = indentWidth; - syncAdapter(); - treeAdapter.refresh(); - } - - public void setIndicatorGravity(final int indicatorGravity) { - this.indicatorGravity = indicatorGravity; - syncAdapter(); - treeAdapter.refresh(); - } - - public void setCollapsible(final boolean collapsible) { - this.collapsible = collapsible; - syncAdapter(); - treeAdapter.refresh(); - } - - public void setHandleTrackballPress(final boolean handleTrackballPress) { - this.handleTrackballPress = handleTrackballPress; - syncAdapter(); - treeAdapter.refresh(); - } - - public Drawable getExpandedDrawable() { - return expandedDrawable; - } - - public Drawable getCollapsedDrawable() { - return collapsedDrawable; - } - - public Drawable getRowBackgroundDrawable() { - return rowBackgroundDrawable; - } - - public Drawable getIndicatorBackgroundDrawable() { - return indicatorBackgroundDrawable; - } - - public int getIndentWidth() { - return indentWidth; - } - - public int getIndicatorGravity() { - return indicatorGravity; - } - - public boolean isCollapsible() { - return collapsible; - } - - public boolean isHandleTrackballPress() { - return handleTrackballPress; - } - -} diff --git a/android-libraries/TreeViewList/src/pl/polidea/treeview/overview.html b/android-libraries/TreeViewList/src/pl/polidea/treeview/overview.html deleted file mode 100644 index bdd09ce9f..000000000 --- a/android-libraries/TreeViewList/src/pl/polidea/treeview/overview.html +++ /dev/null @@ -1,24 +0,0 @@ - - -This is a small utility that provides quite configurable tree view list. -It is based on standard android list view. It separates out different -aspects of the tree: there is a separate list view, tree adapter, tree -state manager and tree state builder. -

-

    -
  • Tree view provides the frame to display the view.
  • -
  • Adapter allows to create visual representation of each tree - node.
  • -
  • State manager provides storage for tree state (connections - between parents and children, collapsed/expanded state). It provides - all the low-level tree manipulation methods.
  • -
  • Tree builder allows to build tree easily providing higher - level methods. The tree can be build either from prepared sequentially - prepared list of nodes (node id, level) or using (parent/child - relationships).
  • -

    For now only in-memory state manager is provided, but Tree State - Manger interface is done in the way that database tree manager even for - large trees is potentially supported. -

- - \ No newline at end of file diff --git a/android-libraries/TreeViewList/src/pl/polidea/treeview/package-info.java b/android-libraries/TreeViewList/src/pl/polidea/treeview/package-info.java deleted file mode 100644 index a622e091b..000000000 --- a/android-libraries/TreeViewList/src/pl/polidea/treeview/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Provides expandable Tree View implementation. - */ -package pl.polidea.treeview; \ No newline at end of file diff --git a/android-libraries/achartengine/.classpath b/android-libraries/achartengine/.classpath deleted file mode 100644 index a4f1e4054..000000000 --- a/android-libraries/achartengine/.classpath +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/android-libraries/achartengine/.project b/android-libraries/achartengine/.project deleted file mode 100644 index fb1c7567a..000000000 --- a/android-libraries/achartengine/.project +++ /dev/null @@ -1,33 +0,0 @@ - - - achartengine - - - - - - com.android.ide.eclipse.adt.ResourceManagerBuilder - - - - - com.android.ide.eclipse.adt.PreCompilerBuilder - - - - - org.eclipse.jdt.core.javabuilder - - - - - com.android.ide.eclipse.adt.ApkBuilder - - - - - - com.android.ide.eclipse.adt.AndroidNature - org.eclipse.jdt.core.javanature - - diff --git a/android-libraries/achartengine/AndroidManifest.xml b/android-libraries/achartengine/AndroidManifest.xml deleted file mode 100644 index 083e05fcf..000000000 --- a/android-libraries/achartengine/AndroidManifest.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - \ No newline at end of file diff --git a/android-libraries/achartengine/extra/LICENSE-2.0.txt b/android-libraries/achartengine/extra/LICENSE-2.0.txt deleted file mode 100644 index d64569567..000000000 --- a/android-libraries/achartengine/extra/LICENSE-2.0.txt +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/android-libraries/achartengine/project.properties b/android-libraries/achartengine/project.properties deleted file mode 100644 index 337e8f37d..000000000 --- a/android-libraries/achartengine/project.properties +++ /dev/null @@ -1,12 +0,0 @@ -# This file is automatically generated by Android Tools. -# Do not modify this file -- YOUR CHANGES WILL BE ERASED! -# -# This file must be checked in Version Control Systems. -# -# To customize properties used by the Ant build system use, -# "ant.properties", and override values to adapt the script to your -# project structure. - -# Project target. -target=android-7 -android.library=true diff --git a/android-libraries/achartengine/src/org/achartengine/ChartFactory.java b/android-libraries/achartengine/src/org/achartengine/ChartFactory.java deleted file mode 100644 index 301f1a8fa..000000000 --- a/android-libraries/achartengine/src/org/achartengine/ChartFactory.java +++ /dev/null @@ -1,708 +0,0 @@ -/** - * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.achartengine; - -import org.achartengine.chart.BarChart; -import org.achartengine.chart.BarChart.Type; -import org.achartengine.chart.BubbleChart; -import org.achartengine.chart.CombinedXYChart; -import org.achartengine.chart.CubicLineChart; -import org.achartengine.chart.DialChart; -import org.achartengine.chart.DoughnutChart; -import org.achartengine.chart.LineChart; -import org.achartengine.chart.PieChart; -import org.achartengine.chart.RangeBarChart; -import org.achartengine.chart.ScatterChart; -import org.achartengine.chart.TimeChart; -import org.achartengine.chart.XYChart; -import org.achartengine.model.CategorySeries; -import org.achartengine.model.MultipleCategorySeries; -import org.achartengine.model.XYMultipleSeriesDataset; -import org.achartengine.renderer.DefaultRenderer; -import org.achartengine.renderer.DialRenderer; -import org.achartengine.renderer.XYMultipleSeriesRenderer; - -import android.content.Context; -import android.content.Intent; - -/** - * Utility methods for creating chart views or intents. - */ -public class ChartFactory { - /** The key for the chart data. */ - public static final String CHART = "chart"; - - /** The key for the chart graphical activity title. */ - public static final String TITLE = "title"; - - private ChartFactory() { - // empty for now - } - - /** - * Creates a line chart view. - * - * @param context the context - * @param dataset the multiple series dataset (cannot be null) - * @param renderer the multiple series renderer (cannot be null) - * @return a line chart graphical view - * @throws IllegalArgumentException if dataset is null or renderer is null or - * if the dataset and the renderer don't include the same number of - * series - */ - public static final GraphicalView getLineChartView(Context context, - XYMultipleSeriesDataset dataset, XYMultipleSeriesRenderer renderer) { - checkParameters(dataset, renderer); - XYChart chart = new LineChart(dataset, renderer); - return new GraphicalView(context, chart); - } - - /** - * Creates a cubic line chart view. - * - * @param context the context - * @param dataset the multiple series dataset (cannot be null) - * @param renderer the multiple series renderer (cannot be null) - * @return a line chart graphical view - * @throws IllegalArgumentException if dataset is null or renderer is null or - * if the dataset and the renderer don't include the same number of - * series - */ - public static final GraphicalView getCubeLineChartView(Context context, - XYMultipleSeriesDataset dataset, XYMultipleSeriesRenderer renderer, float smoothness) { - checkParameters(dataset, renderer); - XYChart chart = new CubicLineChart(dataset, renderer, smoothness); - return new GraphicalView(context, chart); - } - - /** - * Creates a scatter chart view. - * - * @param context the context - * @param dataset the multiple series dataset (cannot be null) - * @param renderer the multiple series renderer (cannot be null) - * @return a scatter chart graphical view - * @throws IllegalArgumentException if dataset is null or renderer is null or - * if the dataset and the renderer don't include the same number of - * series - */ - public static final GraphicalView getScatterChartView(Context context, - XYMultipleSeriesDataset dataset, XYMultipleSeriesRenderer renderer) { - checkParameters(dataset, renderer); - XYChart chart = new ScatterChart(dataset, renderer); - return new GraphicalView(context, chart); - } - - /** - * Creates a bubble chart view. - * - * @param context the context - * @param dataset the multiple series dataset (cannot be null) - * @param renderer the multiple series renderer (cannot be null) - * @return a scatter chart graphical view - * @throws IllegalArgumentException if dataset is null or renderer is null or - * if the dataset and the renderer don't include the same number of - * series - */ - public static final GraphicalView getBubbleChartView(Context context, - XYMultipleSeriesDataset dataset, XYMultipleSeriesRenderer renderer) { - checkParameters(dataset, renderer); - XYChart chart = new BubbleChart(dataset, renderer); - return new GraphicalView(context, chart); - } - - /** - * Creates a time chart view. - * - * @param context the context - * @param dataset the multiple series dataset (cannot be null) - * @param renderer the multiple series renderer (cannot be null) - * @param format the date format pattern to be used for displaying the X axis - * date labels. If null, a default appropriate format will be used. - * @return a time chart graphical view - * @throws IllegalArgumentException if dataset is null or renderer is null or - * if the dataset and the renderer don't include the same number of - * series - */ - public static final GraphicalView getTimeChartView(Context context, - XYMultipleSeriesDataset dataset, XYMultipleSeriesRenderer renderer, String format) { - checkParameters(dataset, renderer); - TimeChart chart = new TimeChart(dataset, renderer); - chart.setDateFormat(format); - return new GraphicalView(context, chart); - } - - /** - * Creates a bar chart view. - * - * @param context the context - * @param dataset the multiple series dataset (cannot be null) - * @param renderer the multiple series renderer (cannot be null) - * @param type the bar chart type - * @return a bar chart graphical view - * @throws IllegalArgumentException if dataset is null or renderer is null or - * if the dataset and the renderer don't include the same number of - * series - */ - public static final GraphicalView getBarChartView(Context context, - XYMultipleSeriesDataset dataset, XYMultipleSeriesRenderer renderer, Type type) { - checkParameters(dataset, renderer); - XYChart chart = new BarChart(dataset, renderer, type); - return new GraphicalView(context, chart); - } - - /** - * Creates a range bar chart view. - * - * @param context the context - * @param dataset the multiple series dataset (cannot be null) - * @param renderer the multiple series renderer (cannot be null) - * @param type the range bar chart type - * @return a bar chart graphical view - * @throws IllegalArgumentException if dataset is null or renderer is null or - * if the dataset and the renderer don't include the same number of - * series - */ - public static final GraphicalView getRangeBarChartView(Context context, - XYMultipleSeriesDataset dataset, XYMultipleSeriesRenderer renderer, Type type) { - checkParameters(dataset, renderer); - XYChart chart = new RangeBarChart(dataset, renderer, type); - return new GraphicalView(context, chart); - } - - /** - * Creates a combined XY chart view. - * - * @param context the context - * @param dataset the multiple series dataset (cannot be null) - * @param renderer the multiple series renderer (cannot be null) - * @param types the chart types (cannot be null) - * @return a combined XY chart graphical view - * @throws IllegalArgumentException if dataset is null or renderer is null or - * if a dataset number of items is different than the number of - * series renderers or number of chart types - */ - public static final GraphicalView getCombinedXYChartView(Context context, - XYMultipleSeriesDataset dataset, XYMultipleSeriesRenderer renderer, String[] types) { - if (dataset == null || renderer == null || types == null - || dataset.getSeriesCount() != types.length) { - throw new IllegalArgumentException( - "Dataset, renderer and types should be not null and the datasets series count should be equal to the types length"); - } - checkParameters(dataset, renderer); - CombinedXYChart chart = new CombinedXYChart(dataset, renderer, types); - return new GraphicalView(context, chart); - } - - /** - * Creates a pie chart intent that can be used to start the graphical view - * activity. - * - * @param context the context - * @param dataset the category series dataset (cannot be null) - * @param renderer the series renderer (cannot be null) - * @return a pie chart view - * @throws IllegalArgumentException if dataset is null or renderer is null or - * if the dataset number of items is different than the number of - * series renderers - */ - public static final GraphicalView getPieChartView(Context context, CategorySeries dataset, - DefaultRenderer renderer) { - checkParameters(dataset, renderer); - PieChart chart = new PieChart(dataset, renderer); - return new GraphicalView(context, chart); - } - - /** - * Creates a dial chart intent that can be used to start the graphical view - * activity. - * - * @param context the context - * @param dataset the category series dataset (cannot be null) - * @param renderer the dial renderer (cannot be null) - * @return a pie chart view - * @throws IllegalArgumentException if dataset is null or renderer is null or - * if the dataset number of items is different than the number of - * series renderers - */ - public static final GraphicalView getDialChartView(Context context, CategorySeries dataset, - DialRenderer renderer) { - checkParameters(dataset, renderer); - DialChart chart = new DialChart(dataset, renderer); - return new GraphicalView(context, chart); - } - - /** - * Creates a doughnut chart intent that can be used to start the graphical - * view activity. - * - * @param context the context - * @param dataset the multiple category series dataset (cannot be null) - * @param renderer the series renderer (cannot be null) - * @return a pie chart view - * @throws IllegalArgumentException if dataset is null or renderer is null or - * if the dataset number of items is different than the number of - * series renderers - */ - public static final GraphicalView getDoughnutChartView(Context context, - MultipleCategorySeries dataset, DefaultRenderer renderer) { - checkParameters(dataset, renderer); - DoughnutChart chart = new DoughnutChart(dataset, renderer); - return new GraphicalView(context, chart); - } - - /** - * - * Creates a line chart intent that can be used to start the graphical view - * activity. - * - * @param context the context - * @param dataset the multiple series dataset (cannot be null) - * @param renderer the multiple series renderer (cannot be null) - * @return a line chart intent - * @throws IllegalArgumentException if dataset is null or renderer is null or - * if the dataset and the renderer don't include the same number of - * series - */ - public static final Intent getLineChartIntent(Context context, XYMultipleSeriesDataset dataset, - XYMultipleSeriesRenderer renderer) { - return getLineChartIntent(context, dataset, renderer, ""); - } - - /** - * - * Creates a cubic line chart intent that can be used to start the graphical - * view activity. - * - * @param context the context - * @param dataset the multiple series dataset (cannot be null) - * @param renderer the multiple series renderer (cannot be null) - * @return a line chart intent - * @throws IllegalArgumentException if dataset is null or renderer is null or - * if the dataset and the renderer don't include the same number of - * series - */ - public static final Intent getCubicLineChartIntent(Context context, - XYMultipleSeriesDataset dataset, XYMultipleSeriesRenderer renderer, float smoothness) { - return getCubicLineChartIntent(context, dataset, renderer, smoothness, ""); - } - - /** - * Creates a scatter chart intent that can be used to start the graphical view - * activity. - * - * @param context the context - * @param dataset the multiple series dataset (cannot be null) - * @param renderer the multiple series renderer (cannot be null) - * @return a scatter chart intent - * @throws IllegalArgumentException if dataset is null or renderer is null or - * if the dataset and the renderer don't include the same number of - * series - */ - public static final Intent getScatterChartIntent(Context context, - XYMultipleSeriesDataset dataset, XYMultipleSeriesRenderer renderer) { - return getScatterChartIntent(context, dataset, renderer, ""); - } - - /** - * Creates a bubble chart intent that can be used to start the graphical view - * activity. - * - * @param context the context - * @param dataset the multiple series dataset (cannot be null) - * @param renderer the multiple series renderer (cannot be null) - * @return a scatter chart intent - * @throws IllegalArgumentException if dataset is null or renderer is null or - * if the dataset and the renderer don't include the same number of - * series - */ - public static final Intent getBubbleChartIntent(Context context, XYMultipleSeriesDataset dataset, - XYMultipleSeriesRenderer renderer) { - return getBubbleChartIntent(context, dataset, renderer, ""); - } - - /** - * Creates a time chart intent that can be used to start the graphical view - * activity. - * - * @param context the context - * @param dataset the multiple series dataset (cannot be null) - * @param renderer the multiple series renderer (cannot be null) - * @param format the date format pattern to be used for displaying the X axis - * date labels. If null, a default appropriate format will be used. - * @return a time chart intent - * @throws IllegalArgumentException if dataset is null or renderer is null or - * if the dataset and the renderer don't include the same number of - * series - */ - public static final Intent getTimeChartIntent(Context context, XYMultipleSeriesDataset dataset, - XYMultipleSeriesRenderer renderer, String format) { - return getTimeChartIntent(context, dataset, renderer, format, ""); - } - - /** - * Creates a bar chart intent that can be used to start the graphical view - * activity. - * - * @param context the context - * @param dataset the multiple series dataset (cannot be null) - * @param renderer the multiple series renderer (cannot be null) - * @param type the bar chart type - * @return a bar chart intent - * @throws IllegalArgumentException if dataset is null or renderer is null or - * if the dataset and the renderer don't include the same number of - * series - */ - public static final Intent getBarChartIntent(Context context, XYMultipleSeriesDataset dataset, - XYMultipleSeriesRenderer renderer, Type type) { - return getBarChartIntent(context, dataset, renderer, type, ""); - } - - /** - * Creates a line chart intent that can be used to start the graphical view - * activity. - * - * @param context the context - * @param dataset the multiple series dataset (cannot be null) - * @param renderer the multiple series renderer (cannot be null) - * @param activityTitle the graphical chart activity title. If this is null, - * then the title bar will be hidden. If a blank title is passed in, - * then the title bar will be the default. Pass in any other string - * to set a custom title. - * @return a line chart intent - * @throws IllegalArgumentException if dataset is null or renderer is null or - * if the dataset and the renderer don't include the same number of - * series - */ - public static final Intent getLineChartIntent(Context context, XYMultipleSeriesDataset dataset, - XYMultipleSeriesRenderer renderer, String activityTitle) { - checkParameters(dataset, renderer); - Intent intent = new Intent(context, GraphicalActivity.class); - XYChart chart = new LineChart(dataset, renderer); - intent.putExtra(CHART, chart); - intent.putExtra(TITLE, activityTitle); - return intent; - } - - /** - * Creates a line chart intent that can be used to start the graphical view - * activity. - * - * @param context the context - * @param dataset the multiple series dataset (cannot be null) - * @param renderer the multiple series renderer (cannot be null) - * @param activityTitle the graphical chart activity title. If this is null, - * then the title bar will be hidden. If a blank title is passed in, - * then the title bar will be the default. Pass in any other string - * to set a custom title. - * @return a line chart intent - * @throws IllegalArgumentException if dataset is null or renderer is null or - * if the dataset and the renderer don't include the same number of - * series - */ - public static final Intent getCubicLineChartIntent(Context context, - XYMultipleSeriesDataset dataset, XYMultipleSeriesRenderer renderer, float smoothness, - String activityTitle) { - checkParameters(dataset, renderer); - Intent intent = new Intent(context, GraphicalActivity.class); - XYChart chart = new CubicLineChart(dataset, renderer, smoothness); - intent.putExtra(CHART, chart); - intent.putExtra(TITLE, activityTitle); - return intent; - } - - /** - * Creates a scatter chart intent that can be used to start the graphical view - * activity. - * - * @param context the context - * @param dataset the multiple series dataset (cannot be null) - * @param renderer the multiple series renderer (cannot be null) - * @param activityTitle the graphical chart activity title - * @return a scatter chart intent - * @throws IllegalArgumentException if dataset is null or renderer is null or - * if the dataset and the renderer don't include the same number of - * series - */ - public static final Intent getScatterChartIntent(Context context, - XYMultipleSeriesDataset dataset, XYMultipleSeriesRenderer renderer, String activityTitle) { - checkParameters(dataset, renderer); - Intent intent = new Intent(context, GraphicalActivity.class); - XYChart chart = new ScatterChart(dataset, renderer); - intent.putExtra(CHART, chart); - intent.putExtra(TITLE, activityTitle); - return intent; - } - - /** - * Creates a bubble chart intent that can be used to start the graphical view - * activity. - * - * @param context the context - * @param dataset the multiple series dataset (cannot be null) - * @param renderer the multiple series renderer (cannot be null) - * @param activityTitle the graphical chart activity title - * @return a scatter chart intent - * @throws IllegalArgumentException if dataset is null or renderer is null or - * if the dataset and the renderer don't include the same number of - * series - */ - public static final Intent getBubbleChartIntent(Context context, XYMultipleSeriesDataset dataset, - XYMultipleSeriesRenderer renderer, String activityTitle) { - checkParameters(dataset, renderer); - Intent intent = new Intent(context, GraphicalActivity.class); - XYChart chart = new BubbleChart(dataset, renderer); - intent.putExtra(CHART, chart); - intent.putExtra(TITLE, activityTitle); - return intent; - } - - /** - * Creates a time chart intent that can be used to start the graphical view - * activity. - * - * @param context the context - * @param dataset the multiple series dataset (cannot be null) - * @param renderer the multiple series renderer (cannot be null) - * @param format the date format pattern to be used for displaying the X axis - * date labels. If null, a default appropriate format will be used - * @param activityTitle the graphical chart activity title - * @return a time chart intent - * @throws IllegalArgumentException if dataset is null or renderer is null or - * if the dataset and the renderer don't include the same number of - * series - */ - public static final Intent getTimeChartIntent(Context context, XYMultipleSeriesDataset dataset, - XYMultipleSeriesRenderer renderer, String format, String activityTitle) { - checkParameters(dataset, renderer); - Intent intent = new Intent(context, GraphicalActivity.class); - TimeChart chart = new TimeChart(dataset, renderer); - chart.setDateFormat(format); - intent.putExtra(CHART, chart); - intent.putExtra(TITLE, activityTitle); - return intent; - } - - /** - * Creates a bar chart intent that can be used to start the graphical view - * activity. - * - * @param context the context - * @param dataset the multiple series dataset (cannot be null) - * @param renderer the multiple series renderer (cannot be null) - * @param type the bar chart type - * @param activityTitle the graphical chart activity title - * @return a bar chart intent - * @throws IllegalArgumentException if dataset is null or renderer is null or - * if the dataset and the renderer don't include the same number of - * series - */ - public static final Intent getBarChartIntent(Context context, XYMultipleSeriesDataset dataset, - XYMultipleSeriesRenderer renderer, Type type, String activityTitle) { - checkParameters(dataset, renderer); - Intent intent = new Intent(context, GraphicalActivity.class); - BarChart chart = new BarChart(dataset, renderer, type); - intent.putExtra(CHART, chart); - intent.putExtra(TITLE, activityTitle); - return intent; - } - - /** - * Creates a range bar chart intent that can be used to start the graphical - * view activity. - * - * @param context the context - * @param dataset the multiple series dataset (cannot be null) - * @param renderer the multiple series renderer (cannot be null) - * @param type the range bar chart type - * @param activityTitle the graphical chart activity title - * @return a range bar chart intent - * @throws IllegalArgumentException if dataset is null or renderer is null or - * if the dataset and the renderer don't include the same number of - * series - */ - public static final Intent getRangeBarChartIntent(Context context, - XYMultipleSeriesDataset dataset, XYMultipleSeriesRenderer renderer, Type type, - String activityTitle) { - checkParameters(dataset, renderer); - Intent intent = new Intent(context, GraphicalActivity.class); - RangeBarChart chart = new RangeBarChart(dataset, renderer, type); - intent.putExtra(CHART, chart); - intent.putExtra(TITLE, activityTitle); - return intent; - } - - /** - * Creates a combined XY chart intent that can be used to start the graphical - * view activity. - * - * @param context the context - * @param dataset the multiple series dataset (cannot be null) - * @param renderer the multiple series renderer (cannot be null) - * @param types the chart types (cannot be null) - * @param activityTitle the graphical chart activity title - * @return a combined XY chart intent - * @throws IllegalArgumentException if dataset is null or renderer is null or - * if a dataset number of items is different than the number of - * series renderers or number of chart types - */ - public static final Intent getCombinedXYChartIntent(Context context, - XYMultipleSeriesDataset dataset, XYMultipleSeriesRenderer renderer, String[] types, - String activityTitle) { - if (dataset == null || renderer == null || types == null - || dataset.getSeriesCount() != types.length) { - throw new IllegalArgumentException( - "Datasets, renderers and types should be not null and the datasets series count should be equal to the types length"); - } - checkParameters(dataset, renderer); - Intent intent = new Intent(context, GraphicalActivity.class); - CombinedXYChart chart = new CombinedXYChart(dataset, renderer, types); - intent.putExtra(CHART, chart); - intent.putExtra(TITLE, activityTitle); - return intent; - } - - /** - * Creates a pie chart intent that can be used to start the graphical view - * activity. - * - * @param context the context - * @param dataset the category series dataset (cannot be null) - * @param renderer the series renderer (cannot be null) - * @param activityTitle the graphical chart activity title - * @return a pie chart intent - * @throws IllegalArgumentException if dataset is null or renderer is null or - * if the dataset number of items is different than the number of - * series renderers - */ - public static final Intent getPieChartIntent(Context context, CategorySeries dataset, - DefaultRenderer renderer, String activityTitle) { - checkParameters(dataset, renderer); - Intent intent = new Intent(context, GraphicalActivity.class); - PieChart chart = new PieChart(dataset, renderer); - intent.putExtra(CHART, chart); - intent.putExtra(TITLE, activityTitle); - return intent; - } - - /** - * Creates a doughnut chart intent that can be used to start the graphical - * view activity. - * - * @param context the context - * @param dataset the multiple category series dataset (cannot be null) - * @param renderer the series renderer (cannot be null) - * @param activityTitle the graphical chart activity title - * @return a pie chart intent - * @throws IllegalArgumentException if dataset is null or renderer is null or - * if the dataset number of items is different than the number of - * series renderers - */ - public static final Intent getDoughnutChartIntent(Context context, - MultipleCategorySeries dataset, DefaultRenderer renderer, String activityTitle) { - checkParameters(dataset, renderer); - Intent intent = new Intent(context, GraphicalActivity.class); - DoughnutChart chart = new DoughnutChart(dataset, renderer); - intent.putExtra(CHART, chart); - intent.putExtra(TITLE, activityTitle); - return intent; - } - - /** - * Creates a dial chart intent that can be used to start the graphical view - * activity. - * - * @param context the context - * @param dataset the category series dataset (cannot be null) - * @param renderer the dial renderer (cannot be null) - * @param activityTitle the graphical chart activity title - * @return a dial chart intent - * @throws IllegalArgumentException if dataset is null or renderer is null or - * if the dataset number of items is different than the number of - * series renderers - */ - public static final Intent getDialChartIntent(Context context, CategorySeries dataset, - DialRenderer renderer, String activityTitle) { - checkParameters(dataset, renderer); - Intent intent = new Intent(context, GraphicalActivity.class); - DialChart chart = new DialChart(dataset, renderer); - intent.putExtra(CHART, chart); - intent.putExtra(TITLE, activityTitle); - return intent; - } - - /** - * Checks the validity of the dataset and renderer parameters. - * - * @param dataset the multiple series dataset (cannot be null) - * @param renderer the multiple series renderer (cannot be null) - * @throws IllegalArgumentException if dataset is null or renderer is null or - * if the dataset and the renderer don't include the same number of - * series - */ - private static void checkParameters(XYMultipleSeriesDataset dataset, - XYMultipleSeriesRenderer renderer) { - if (dataset == null || renderer == null - || dataset.getSeriesCount() != renderer.getSeriesRendererCount()) { - throw new IllegalArgumentException( - "Dataset and renderer should be not null and should have the same number of series"); - } - } - - /** - * Checks the validity of the dataset and renderer parameters. - * - * @param dataset the category series dataset (cannot be null) - * @param renderer the series renderer (cannot be null) - * @throws IllegalArgumentException if dataset is null or renderer is null or - * if the dataset number of items is different than the number of - * series renderers - */ - private static void checkParameters(CategorySeries dataset, DefaultRenderer renderer) { - if (dataset == null || renderer == null - || dataset.getItemCount() != renderer.getSeriesRendererCount()) { - throw new IllegalArgumentException( - "Dataset and renderer should be not null and the dataset number of items should be equal to the number of series renderers"); - } - } - - /** - * Checks the validity of the dataset and renderer parameters. - * - * @param dataset the category series dataset (cannot be null) - * @param renderer the series renderer (cannot be null) - * @throws IllegalArgumentException if dataset is null or renderer is null or - * if the dataset number of items is different than the number of - * series renderers - */ - private static void checkParameters(MultipleCategorySeries dataset, DefaultRenderer renderer) { - if (dataset == null || renderer == null - || !checkMultipleSeriesItems(dataset, renderer.getSeriesRendererCount())) { - throw new IllegalArgumentException( - "Titles and values should be not null and the dataset number of items should be equal to the number of series renderers"); - } - } - - private static boolean checkMultipleSeriesItems(MultipleCategorySeries dataset, int value) { - int count = dataset.getCategoriesCount(); - boolean equal = true; - for (int k = 0; k < count && equal; k++) { - equal = dataset.getValues(k).length == dataset.getTitles(k).length; - } - return equal; - } - -} diff --git a/android-libraries/achartengine/src/org/achartengine/GraphicalActivity.java b/android-libraries/achartengine/src/org/achartengine/GraphicalActivity.java deleted file mode 100644 index 56c190aef..000000000 --- a/android-libraries/achartengine/src/org/achartengine/GraphicalActivity.java +++ /dev/null @@ -1,48 +0,0 @@ -/** - * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.achartengine; - -import org.achartengine.chart.AbstractChart; - -import android.app.Activity; -import android.os.Bundle; -import android.view.Window; - -/** - * An activity that encapsulates a graphical view of the chart. - */ -public class GraphicalActivity extends Activity { - /** The encapsulated graphical view. */ - private GraphicalView mView; - /** The chart to be drawn. */ - private AbstractChart mChart; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - Bundle extras = getIntent().getExtras(); - mChart = (AbstractChart) extras.getSerializable(ChartFactory.CHART); - mView = new GraphicalView(this, mChart); - String title = extras.getString(ChartFactory.TITLE); - if (title == null) { - requestWindowFeature(Window.FEATURE_NO_TITLE); - } else if (title.length() > 0) { - setTitle(title); - } - setContentView(mView); - } - -} \ No newline at end of file diff --git a/android-libraries/achartengine/src/org/achartengine/GraphicalView.java b/android-libraries/achartengine/src/org/achartengine/GraphicalView.java deleted file mode 100644 index e9aebff53..000000000 --- a/android-libraries/achartengine/src/org/achartengine/GraphicalView.java +++ /dev/null @@ -1,337 +0,0 @@ -/** - * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.achartengine; - -import org.achartengine.chart.AbstractChart; -import org.achartengine.chart.RoundChart; -import org.achartengine.chart.XYChart; -import org.achartengine.model.Point; -import org.achartengine.model.SeriesSelection; -import org.achartengine.renderer.DefaultRenderer; -import org.achartengine.renderer.XYMultipleSeriesRenderer; -import org.achartengine.tools.FitZoom; -import org.achartengine.tools.PanListener; -import org.achartengine.tools.Zoom; -import org.achartengine.tools.ZoomListener; - -import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Paint; -import android.graphics.Rect; -import android.graphics.RectF; -import android.os.Build; -import android.os.Handler; -import android.view.MotionEvent; -import android.view.View; - -/** - * The view that encapsulates the graphical chart. - */ -public class GraphicalView extends View { - /** The chart to be drawn. */ - private AbstractChart mChart; - /** The chart renderer. */ - private DefaultRenderer mRenderer; - /** The view bounds. */ - private Rect mRect = new Rect(); - /** The user interface thread handler. */ - private Handler mHandler; - /** The zoom buttons rectangle. */ - private RectF mZoomR = new RectF(); - /** The zoom in icon. */ - private Bitmap zoomInImage; - /** The zoom out icon. */ - private Bitmap zoomOutImage; - /** The fit zoom icon. */ - private Bitmap fitZoomImage; - /** The zoom area size. */ - private int zoomSize = 50; - /** The zoom buttons background color. */ - private static final int ZOOM_BUTTONS_COLOR = Color.argb(175, 150, 150, 150); - /** The zoom in tool. */ - private Zoom mZoomIn; - /** The zoom out tool. */ - private Zoom mZoomOut; - /** The fit zoom tool. */ - private FitZoom mFitZoom; - /** The paint to be used when drawing the chart. */ - private Paint mPaint = new Paint(); - /** The touch handler. */ - private ITouchHandler mTouchHandler; - /** The old x coordinate. */ - private float oldX; - /** The old y coordinate. */ - private float oldY; - - /** - * Creates a new graphical view. - * - * @param context the context - * @param chart the chart to be drawn - */ - public GraphicalView(Context context, AbstractChart chart) { - super(context); - mChart = chart; - mHandler = new Handler(); - if (mChart instanceof XYChart) { - mRenderer = ((XYChart) mChart).getRenderer(); - } else { - mRenderer = ((RoundChart) mChart).getRenderer(); - } - if (mRenderer.isZoomButtonsVisible()) { - zoomInImage = BitmapFactory.decodeStream(GraphicalView.class - .getResourceAsStream("image/zoom_in.png")); - zoomOutImage = BitmapFactory.decodeStream(GraphicalView.class - .getResourceAsStream("image/zoom_out.png")); - fitZoomImage = BitmapFactory.decodeStream(GraphicalView.class - .getResourceAsStream("image/zoom-1.png")); - } - - if (mRenderer instanceof XYMultipleSeriesRenderer - && ((XYMultipleSeriesRenderer) mRenderer).getMarginsColor() == XYMultipleSeriesRenderer.NO_COLOR) { - ((XYMultipleSeriesRenderer) mRenderer).setMarginsColor(mPaint.getColor()); - } - if (mRenderer.isZoomEnabled() && mRenderer.isZoomButtonsVisible() - || mRenderer.isExternalZoomEnabled()) { - mZoomIn = new Zoom(mChart, true, mRenderer.getZoomRate()); - mZoomOut = new Zoom(mChart, false, mRenderer.getZoomRate()); - mFitZoom = new FitZoom(mChart); - } - int version = 7; - try { - version = Integer.valueOf(Build.VERSION.SDK); - } catch (Exception e) { - // do nothing - } - if (version < 7) { - mTouchHandler = new TouchHandlerOld(this, mChart); - } else { - mTouchHandler = new TouchHandler(this, mChart); - } - } - - /** - * Returns the current series selection object. - * - * @return the series selection - */ - public SeriesSelection getCurrentSeriesAndPoint() { - return mChart.getSeriesAndPointForScreenCoordinate(new Point(oldX, oldY)); - } - - /** - * Transforms the currently selected screen point to a real point. - * - * @param scale the scale - * @return the currently selected real point - */ - public double[] toRealPoint(int scale) { - if (mChart instanceof XYChart) { - XYChart chart = (XYChart) mChart; - return chart.toRealPoint(oldX, oldY, scale); - } - return null; - } - - @Override - protected void onDraw(Canvas canvas) { - super.onDraw(canvas); - canvas.getClipBounds(mRect); - int top = mRect.top; - int left = mRect.left; - int width = mRect.width(); - int height = mRect.height(); - if (mRenderer.isInScroll()) { - top = 0; - left = 0; - width = getMeasuredWidth(); - height = getMeasuredHeight(); - } - mChart.draw(canvas, left, top, width, height, mPaint); - if (mRenderer != null && mRenderer.isZoomEnabled() && mRenderer.isZoomButtonsVisible()) { - mPaint.setColor(ZOOM_BUTTONS_COLOR); - zoomSize = Math.max(zoomSize, Math.min(width, height) / 7); - mZoomR.set(left + width - zoomSize * 3, top + height - zoomSize * 0.775f, left + width, top - + height); - canvas.drawRoundRect(mZoomR, zoomSize / 3, zoomSize / 3, mPaint); - float buttonY = top + height - zoomSize * 0.625f; - canvas.drawBitmap(zoomInImage, left + width - zoomSize * 2.75f, buttonY, null); - canvas.drawBitmap(zoomOutImage, left + width - zoomSize * 1.75f, buttonY, null); - canvas.drawBitmap(fitZoomImage, left + width - zoomSize * 0.75f, buttonY, null); - } - } - - /** - * Sets the zoom rate. - * - * @param rate the zoom rate - */ - public void setZoomRate(float rate) { - if (mZoomIn != null && mZoomOut != null) { - mZoomIn.setZoomRate(rate); - mZoomOut.setZoomRate(rate); - } - } - - /** - * Do a chart zoom in. - */ - public void zoomIn() { - if (mZoomIn != null) { - mZoomIn.apply(Zoom.ZOOM_AXIS_XY); - repaint(); - } - } - - /** - * Do a chart zoom out. - */ - public void zoomOut() { - if (mZoomOut != null) { - mZoomOut.apply(Zoom.ZOOM_AXIS_XY); - repaint(); - } - } - - - - /** - * Do a chart zoom reset / fit zoom. - */ - public void zoomReset() { - if (mFitZoom != null) { - mFitZoom.apply(); - mZoomIn.notifyZoomResetListeners(); - repaint(); - } - } - - /** - * Adds a new zoom listener. - * - * @param listener zoom listener - */ - public void addZoomListener(ZoomListener listener, boolean onButtons, boolean onPinch) { - if (onButtons) { - if (mZoomIn != null) { - mZoomIn.addZoomListener(listener); - mZoomOut.addZoomListener(listener); - } - if (onPinch) { - mTouchHandler.addZoomListener(listener); - } - } - } - - /** - * Removes a zoom listener. - * - * @param listener zoom listener - */ - public synchronized void removeZoomListener(ZoomListener listener) { - if (mZoomIn != null) { - mZoomIn.removeZoomListener(listener); - mZoomOut.removeZoomListener(listener); - } - mTouchHandler.removeZoomListener(listener); - } - - /** - * Adds a new pan listener. - * - * @param listener pan listener - */ - public void addPanListener(PanListener listener) { - mTouchHandler.addPanListener(listener); - } - - /** - * Removes a pan listener. - * - * @param listener pan listener - */ - public void removePanListener(PanListener listener) { - mTouchHandler.removePanListener(listener); - } - - protected RectF getZoomRectangle() { - return mZoomR; - } - - @Override - public boolean onTouchEvent(MotionEvent event) { - if (event.getAction() == MotionEvent.ACTION_DOWN) { - // save the x and y so they can be used in the click and long press - // listeners - oldX = event.getX(); - oldY = event.getY(); - } - if (mRenderer != null && (mRenderer.isPanEnabled() || mRenderer.isZoomEnabled())) { - if (mTouchHandler.handleTouch(event)) { - return true; - } - } - return super.onTouchEvent(event); - } - - /** - * Schedule a view content repaint. - */ - public void repaint() { - mHandler.post(new Runnable() { - public void run() { - invalidate(); - } - }); - } - - /** - * Schedule a view content repaint, in the specified rectangle area. - * - * @param left the left position of the area to be repainted - * @param top the top position of the area to be repainted - * @param right the right position of the area to be repainted - * @param bottom the bottom position of the area to be repainted - */ - public void repaint(final int left, final int top, final int right, final int bottom) { - mHandler.post(new Runnable() { - public void run() { - invalidate(left, top, right, bottom); - } - }); - } - - /** - * Saves the content of the graphical view to a bitmap. - * - * @return the bitmap - */ - public Bitmap toBitmap() { - setDrawingCacheEnabled(false); - if (!isDrawingCacheEnabled()) { - setDrawingCacheEnabled(true); - } - if (mRenderer.isApplyBackgroundColor()) { - setDrawingCacheBackgroundColor(mRenderer.getBackgroundColor()); - } - setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH); - return getDrawingCache(true); - } - -} \ No newline at end of file diff --git a/android-libraries/achartengine/src/org/achartengine/ITouchHandler.java b/android-libraries/achartengine/src/org/achartengine/ITouchHandler.java deleted file mode 100644 index 4debe9649..000000000 --- a/android-libraries/achartengine/src/org/achartengine/ITouchHandler.java +++ /dev/null @@ -1,63 +0,0 @@ -/** - * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.achartengine; - -import org.achartengine.tools.PanListener; -import org.achartengine.tools.ZoomListener; - -import android.view.MotionEvent; - -/** - * The interface to be implemented by the touch handlers. - */ -public interface ITouchHandler { - /** - * Handles the touch event. - * - * @param event the touch event - * @return true if the event was handled - */ - boolean handleTouch(MotionEvent event); - - /** - * Adds a new zoom listener. - * - * @param listener zoom listener - */ - void addZoomListener(ZoomListener listener); - - /** - * Removes a zoom listener. - * - * @param listener zoom listener - */ - void removeZoomListener(ZoomListener listener); - - /** - * Adds a new pan listener. - * - * @param listener pan listener - */ - void addPanListener(PanListener listener); - - /** - * Removes a pan listener. - * - * @param listener pan listener - */ - void removePanListener(PanListener listener); - -} \ No newline at end of file diff --git a/android-libraries/achartengine/src/org/achartengine/TouchHandler.java b/android-libraries/achartengine/src/org/achartengine/TouchHandler.java deleted file mode 100644 index a06d05d63..000000000 --- a/android-libraries/achartengine/src/org/achartengine/TouchHandler.java +++ /dev/null @@ -1,204 +0,0 @@ -/** - * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.achartengine; - -import org.achartengine.chart.AbstractChart; -import org.achartengine.chart.RoundChart; -import org.achartengine.chart.XYChart; -import org.achartengine.renderer.DefaultRenderer; -import org.achartengine.tools.Pan; -import org.achartengine.tools.PanListener; -import org.achartengine.tools.Zoom; -import org.achartengine.tools.ZoomListener; - -import android.graphics.RectF; -import android.view.MotionEvent; - -/** - * The main handler of the touch events. - */ -public class TouchHandler implements ITouchHandler { - /** The chart renderer. */ - private DefaultRenderer mRenderer; - /** The old x coordinate. */ - private float oldX; - /** The old y coordinate. */ - private float oldY; - /** The old x2 coordinate. */ - private float oldX2; - /** The old y2 coordinate. */ - private float oldY2; - /** The zoom buttons rectangle. */ - private RectF zoomR = new RectF(); - /** The pan tool. */ - private Pan mPan; - /** The zoom for the pinch gesture. */ - private Zoom mPinchZoom; - /** The graphical view. */ - private GraphicalView graphicalView; - - /** - * Creates a new graphical view. - * - * @param view the graphical view - * @param chart the chart to be drawn - */ - public TouchHandler(GraphicalView view, AbstractChart chart) { - graphicalView = view; - zoomR = graphicalView.getZoomRectangle(); - if (chart instanceof XYChart) { - mRenderer = ((XYChart) chart).getRenderer(); - } else { - mRenderer = ((RoundChart) chart).getRenderer(); - } - if (mRenderer.isPanEnabled()) { - mPan = new Pan(chart); - } - if (mRenderer.isZoomEnabled()) { - mPinchZoom = new Zoom(chart, true, 1); - } - } - - /** - * Handles the touch event. - * - * @param event the touch event - */ - public boolean handleTouch(MotionEvent event) { - int action = event.getAction(); - if (mRenderer != null && action == MotionEvent.ACTION_MOVE) { - if (oldX >= 0 || oldY >= 0) { - float newX = event.getX(0); - float newY = event.getY(0); - if (event.getPointerCount() > 1 && (oldX2 >= 0 || oldY2 >= 0) && mRenderer.isZoomEnabled()) { - float newX2 = event.getX(1); - float newY2 = event.getY(1); - float newDeltaX = Math.abs(newX - newX2); - float newDeltaY = Math.abs(newY - newY2); - float oldDeltaX = Math.abs(oldX - oldX2); - float oldDeltaY = Math.abs(oldY - oldY2); - float zoomRate = 1; - - float tan1 = Math.abs(newY - oldY) / Math.abs(newX - oldX); - float tan2 = Math.abs(newY2 - oldY2) / Math.abs(newX2 - oldX2); - if ( tan1 <= 0.577 && tan2 <= 0.577) { - // horizontal pinch zoom, |deltaY| / |deltaX| is [0 ~ 0.577], 0.577 is the approximate value of tan(Pi/6) - zoomRate = newDeltaX / oldDeltaX; - if (zoomRate > 0.909 && zoomRate < 1.1) { - mPinchZoom.setZoomRate(zoomRate); - mPinchZoom.apply(Zoom.ZOOM_AXIS_X); - } - } else if ( tan1 >= 1.732 && tan2 >= 1.732 ) { - // pinch zoom vertically, |deltaY| / |deltaX| is [1.732 ~ infinity], 1.732 is the approximate value of tan(Pi/3) - zoomRate = newDeltaY / oldDeltaY; - if (zoomRate > 0.909 && zoomRate < 1.1) { - mPinchZoom.setZoomRate(zoomRate); - mPinchZoom.apply(Zoom.ZOOM_AXIS_Y); - } - } else if ( (tan1 > 0.577 && tan1 < 1.732) && (tan2 > 0.577 && tan2 < 1.732) ){ - // pinch zoom diagonally - if (Math.abs(newX - oldX) >= Math.abs(newY - oldY)) { - zoomRate = newDeltaX / oldDeltaX; - } else { - zoomRate = newDeltaY / oldDeltaY; - } - if (zoomRate > 0.909 && zoomRate < 1.1) { - mPinchZoom.setZoomRate(zoomRate); - mPinchZoom.apply(Zoom.ZOOM_AXIS_XY); - } - } - oldX2 = newX2; - oldY2 = newY2; - } else if (mRenderer.isPanEnabled()) { - mPan.apply(oldX, oldY, newX, newY); - oldX2 = 0; - oldY2 = 0; - } - oldX = newX; - oldY = newY; - graphicalView.repaint(); - return true; - } - } else if (action == MotionEvent.ACTION_DOWN) { - oldX = event.getX(0); - oldY = event.getY(0); - if (mRenderer != null && mRenderer.isZoomEnabled() && zoomR.contains(oldX, oldY)) { - if (oldX < zoomR.left + zoomR.width() / 3) { - graphicalView.zoomIn(); - } else if (oldX < zoomR.left + zoomR.width() * 2 / 3) { - graphicalView.zoomOut(); - } else { - graphicalView.zoomReset(); - } - return true; - } - } else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_POINTER_UP) { - oldX = 0; - oldY = 0; - oldX2 = 0; - oldY2 = 0; - if (action == MotionEvent.ACTION_POINTER_UP) { - oldX = -1; - oldY = -1; - } - } - return !mRenderer.isClickEnabled(); - } - - /** - * Adds a new zoom listener. - * - * @param listener zoom listener - */ - public void addZoomListener(ZoomListener listener) { - if (mPinchZoom != null) { - mPinchZoom.addZoomListener(listener); - } - } - - /** - * Removes a zoom listener. - * - * @param listener zoom listener - */ - public void removeZoomListener(ZoomListener listener) { - if (mPinchZoom != null) { - mPinchZoom.removeZoomListener(listener); - } - } - - /** - * Adds a new pan listener. - * - * @param listener pan listener - */ - public void addPanListener(PanListener listener) { - if (mPan != null) { - mPan.addPanListener(listener); - } - } - - /** - * Removes a pan listener. - * - * @param listener pan listener - */ - public void removePanListener(PanListener listener) { - if (mPan != null) { - mPan.removePanListener(listener); - } - } -} \ No newline at end of file diff --git a/android-libraries/achartengine/src/org/achartengine/TouchHandlerOld.java b/android-libraries/achartengine/src/org/achartengine/TouchHandlerOld.java deleted file mode 100644 index 38b4f227b..000000000 --- a/android-libraries/achartengine/src/org/achartengine/TouchHandlerOld.java +++ /dev/null @@ -1,137 +0,0 @@ -/** - * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.achartengine; - -import org.achartengine.chart.AbstractChart; -import org.achartengine.chart.RoundChart; -import org.achartengine.chart.XYChart; -import org.achartengine.renderer.DefaultRenderer; -import org.achartengine.tools.Pan; -import org.achartengine.tools.PanListener; -import org.achartengine.tools.ZoomListener; - -import android.graphics.RectF; -import android.view.MotionEvent; - -/** - * A handler implementation for touch events for older platforms. - */ -public class TouchHandlerOld implements ITouchHandler { - /** The chart renderer. */ - private DefaultRenderer mRenderer; - /** The old x coordinate. */ - private float oldX; - /** The old y coordinate. */ - private float oldY; - /** The zoom buttons rectangle. */ - private RectF zoomR = new RectF(); - /** The pan tool. */ - private Pan mPan; - /** The graphical view. */ - private GraphicalView graphicalView; - - /** - * Creates an implementation of the old version of the touch handler. - * - * @param view the graphical view - * @param chart the chart to be drawn - */ - public TouchHandlerOld(GraphicalView view, AbstractChart chart) { - graphicalView = view; - zoomR = graphicalView.getZoomRectangle(); - if (chart instanceof XYChart) { - mRenderer = ((XYChart) chart).getRenderer(); - } else { - mRenderer = ((RoundChart) chart).getRenderer(); - } - if (mRenderer.isPanEnabled()) { - mPan = new Pan(chart); - } - } - - public boolean handleTouch(MotionEvent event) { - int action = event.getAction(); - if (mRenderer != null && action == MotionEvent.ACTION_MOVE) { - if (oldX >= 0 || oldY >= 0) { - float newX = event.getX(); - float newY = event.getY(); - if (mRenderer.isPanEnabled()) { - mPan.apply(oldX, oldY, newX, newY); - } - oldX = newX; - oldY = newY; - graphicalView.repaint(); - return true; - } - } else if (action == MotionEvent.ACTION_DOWN) { - oldX = event.getX(); - oldY = event.getY(); - if (mRenderer != null && mRenderer.isZoomEnabled() && zoomR.contains(oldX, oldY)) { - if (oldX < zoomR.left + zoomR.width() / 3) { - graphicalView.zoomIn(); - } else if (oldX < zoomR.left + zoomR.width() * 2 / 3) { - graphicalView.zoomOut(); - } else { - graphicalView.zoomReset(); - } - return true; - } - } else if (action == MotionEvent.ACTION_UP) { - oldX = 0; - oldY = 0; - } - return !mRenderer.isClickEnabled(); - } - - /** - * Adds a new zoom listener. - * - * @param listener zoom listener - */ - public void addZoomListener(ZoomListener listener) { - } - - /** - * Removes a zoom listener. - * - * @param listener zoom listener - */ - public void removeZoomListener(ZoomListener listener) { - } - - /** - * Adds a new pan listener. - * - * @param listener pan listener - */ - public void addPanListener(PanListener listener) { - if (mPan != null) { - mPan.addPanListener(listener); - } - } - - /** - * Removes a pan listener. - * - * @param listener pan listener - */ - public void removePanListener(PanListener listener) { - if (mPan != null) { - mPan.removePanListener(listener); - } - } - -} \ No newline at end of file diff --git a/android-libraries/achartengine/src/org/achartengine/chart/AbstractChart.java b/android-libraries/achartengine/src/org/achartengine/chart/AbstractChart.java deleted file mode 100644 index f99a5c2a8..000000000 --- a/android-libraries/achartengine/src/org/achartengine/chart/AbstractChart.java +++ /dev/null @@ -1,475 +0,0 @@ -/** - * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.achartengine.chart; - -import java.io.Serializable; -import java.util.List; - -import org.achartengine.model.Point; -import org.achartengine.model.SeriesSelection; -import org.achartengine.renderer.DefaultRenderer; -import org.achartengine.renderer.SimpleSeriesRenderer; -import org.achartengine.renderer.XYMultipleSeriesRenderer; -import org.achartengine.renderer.XYMultipleSeriesRenderer.Orientation; -import org.achartengine.util.MathHelper; - -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Paint; -import android.graphics.Paint.Align; -import android.graphics.Paint.Style; -import android.graphics.Path; -import android.graphics.Rect; -import android.graphics.RectF; - -/** - * An abstract class to be implemented by the chart rendering classes. - */ -public abstract class AbstractChart implements Serializable { - /** - * The graphical representation of the chart. - * - * @param canvas the canvas to paint to - * @param x the top left x value of the view to draw to - * @param y the top left y value of the view to draw to - * @param width the width of the view to draw to - * @param height the height of the view to draw to - * @param paint the paint - */ - public abstract void draw(Canvas canvas, int x, int y, int width, int height, Paint paint); - - /** - * Draws the chart background. - * - * @param renderer the chart renderer - * @param canvas the canvas to paint to - * @param x the top left x value of the view to draw to - * @param y the top left y value of the view to draw to - * @param width the width of the view to draw to - * @param height the height of the view to draw to - * @param paint the paint used for drawing - * @param newColor if a new color is to be used - * @param color the color to be used - */ - protected void drawBackground(DefaultRenderer renderer, Canvas canvas, int x, int y, int width, - int height, Paint paint, boolean newColor, int color) { - if (renderer.isApplyBackgroundColor() || newColor) { - if (newColor) { - paint.setColor(color); - } else { - paint.setColor(renderer.getBackgroundColor()); - } - paint.setStyle(Style.FILL); - canvas.drawRect(x, y, x + width, y + height, paint); - } - } - - /** - * Draws the chart legend. - * - * @param canvas the canvas to paint to - * @param renderer the series renderer - * @param titles the titles to go to the legend - * @param left the left X value of the area to draw to - * @param right the right X value of the area to draw to - * @param y the y value of the area to draw to - * @param width the width of the area to draw to - * @param height the height of the area to draw to - * @param legendSize the legend size - * @param paint the paint to be used for drawing - * @param calculate if only calculating the legend size - * - * @return the legend height - */ - protected int drawLegend(Canvas canvas, DefaultRenderer renderer, String[] titles, int left, - int right, int y, int width, int height, int legendSize, Paint paint, boolean calculate) { - float size = 32; - if (renderer.isShowLegend()) { - float currentX = left; - float currentY = y + height - legendSize + size; - paint.setTextAlign(Align.LEFT); - paint.setTextSize(renderer.getLegendTextSize()); - int sLength = Math.min(titles.length, renderer.getSeriesRendererCount()); - for (int i = 0; i < sLength; i++) { - final float lineSize = getLegendShapeWidth(i); - String text = titles[i]; - if (titles.length == renderer.getSeriesRendererCount()) { - paint.setColor(renderer.getSeriesRendererAt(i).getColor()); - } else { - paint.setColor(Color.LTGRAY); - } - float[] widths = new float[text.length()]; - paint.getTextWidths(text, widths); - float sum = 0; - for (float value : widths) { - sum += value; - } - float extraSize = lineSize + 10 + sum; - float currentWidth = currentX + extraSize; - - if (i > 0 && getExceed(currentWidth, renderer, right, width)) { - currentX = left; - currentY += renderer.getLegendTextSize(); - size += renderer.getLegendTextSize(); - currentWidth = currentX + extraSize; - } - if (getExceed(currentWidth, renderer, right, width)) { - float maxWidth = right - currentX - lineSize - 10; - if (isVertical(renderer)) { - maxWidth = width - currentX - lineSize - 10; - } - int nr = paint.breakText(text, true, maxWidth, widths); - text = text.substring(0, nr) + "..."; - } - if (!calculate) { - drawLegendShape(canvas, renderer.getSeriesRendererAt(i), currentX, currentY, i, paint); - drawString(canvas, text, currentX + lineSize + 5, currentY + 5, paint); - } - currentX += extraSize; - } - } - return Math.round(size + renderer.getLegendTextSize()); - } - - /** - * Draw a multiple lines string. - * - * @param canvas the canvas to paint to - * @param text the text to be painted - * @param x the x value of the area to draw to - * @param y the y value of the area to draw to - * @param paint the paint to be used for drawing - */ - protected void drawString(Canvas canvas, String text, float x, float y, Paint paint) { - String[] lines = text.split("\n"); - Rect rect = new Rect(); - int yOff = 0; - for (int i = 0; i < lines.length; ++i) { - canvas.drawText(lines[i], x, y + yOff, paint); - paint.getTextBounds(lines[i], 0, lines[i].length(), rect); - yOff = yOff + rect.height() + 5; // space between lines is 5 - } - } - - /** - * Calculates if the current width exceeds the total width. - * - * @param currentWidth the current width - * @param renderer the renderer - * @param right the right side pixel value - * @param width the total width - * @return if the current width exceeds the total width - */ - protected boolean getExceed(float currentWidth, DefaultRenderer renderer, int right, int width) { - boolean exceed = currentWidth > right; - if (isVertical(renderer)) { - exceed = currentWidth > width; - } - return exceed; - } - - /** - * Checks if the current chart is rendered as vertical. - * - * @param renderer the renderer - * @return if the chart is rendered as a vertical one - */ - public boolean isVertical(DefaultRenderer renderer) { - return renderer instanceof XYMultipleSeriesRenderer - && ((XYMultipleSeriesRenderer) renderer).getOrientation() == Orientation.VERTICAL; - } - - /** - * Makes sure the fraction digit is not displayed, if not needed. - * - * @param label the input label value - * @return the label without the useless fraction digit - */ - protected String getLabel(double label) { - String text = ""; - if (label == Math.round(label)) { - text = Math.round(label) + ""; - } else { - text = label + ""; - } - return text; - } - - private static float[] calculateDrawPoints(float p1x, float p1y, float p2x, float p2y, - int screenHeight, int screenWidth) { - float drawP1x; - float drawP1y; - float drawP2x; - float drawP2y; - - if (p1y > screenHeight) { - // Intersection with the top of the screen - float m = (p2y - p1y) / (p2x - p1x); - drawP1x = (screenHeight - p1y + m * p1x) / m; - drawP1y = screenHeight; - - if (drawP1x < 0) { - // If Intersection is left of the screen we calculate the intersection - // with the left border - drawP1x = 0; - drawP1y = p1y - m * p1x; - } else if (drawP1x > screenWidth) { - // If Intersection is right of the screen we calculate the intersection - // with the right border - drawP1x = screenWidth; - drawP1y = m * screenWidth + p1y - m * p1x; - } - } else if (p1y < 0) { - float m = (p2y - p1y) / (p2x - p1x); - drawP1x = (-p1y + m * p1x) / m; - drawP1y = 0; - if (drawP1x < 0) { - drawP1x = 0; - drawP1y = p1y - m * p1x; - } else if (drawP1x > screenWidth) { - drawP1x = screenWidth; - drawP1y = m * screenWidth + p1y - m * p1x; - } - } else { - // If the point is in the screen use it - drawP1x = p1x; - drawP1y = p1y; - } - - if (p2y > screenHeight) { - float m = (p2y - p1y) / (p2x - p1x); - drawP2x = (screenHeight - p1y + m * p1x) / m; - drawP2y = screenHeight; - if (drawP2x < 0) { - drawP2x = 0; - drawP2y = p1y - m * p1x; - } else if (drawP2x > screenWidth) { - drawP2x = screenWidth; - drawP2y = m * screenWidth + p1y - m * p1x; - } - } else if (p2y < 0) { - float m = (p2y - p1y) / (p2x - p1x); - drawP2x = (-p1y + m * p1x) / m; - drawP2y = 0; - if (drawP2x < 0) { - drawP2x = 0; - drawP2y = p1y - m * p1x; - } else if (drawP2x > screenWidth) { - drawP2x = screenWidth; - drawP2y = m * screenWidth + p1y - m * p1x; - } - } else { - // If the point is in the screen use it - drawP2x = p2x; - drawP2y = p2y; - } - - return new float[] { drawP1x, drawP1y, drawP2x, drawP2y }; - } - - /** - * The graphical representation of a path. - * - * @param canvas the canvas to paint to - * @param points the points that are contained in the path to paint - * @param paint the paint to be used for painting - * @param circular if the path ends with the start point - */ - protected void drawPath(Canvas canvas, float[] points, Paint paint, boolean circular) { - Path path = new Path(); - int height = canvas.getHeight(); - int width = canvas.getWidth(); - - float[] tempDrawPoints; - if (points.length < 4) { - return; - } - tempDrawPoints = calculateDrawPoints(points[0], points[1], points[2], points[3], height, width); - path.moveTo(tempDrawPoints[0], tempDrawPoints[1]); - path.lineTo(tempDrawPoints[2], tempDrawPoints[3]); - - for (int i = 4; i < points.length; i += 2) { - if ((points[i - 1] < 0 && points[i + 1] < 0) - || (points[i - 1] > height && points[i + 1] > height)) { - continue; - } - tempDrawPoints = calculateDrawPoints(points[i - 2], points[i - 1], points[i], points[i + 1], - height, width); - if (!circular) { - path.moveTo(tempDrawPoints[0], tempDrawPoints[1]); - } - path.lineTo(tempDrawPoints[2], tempDrawPoints[3]); - } - if (circular) { - path.lineTo(points[0], points[1]); - } - canvas.drawPath(path, paint); - } - - /** - * Returns the legend shape width. - * - * @param seriesIndex the series index - * @return the legend shape width - */ - public abstract int getLegendShapeWidth(int seriesIndex); - - /** - * The graphical representation of the legend shape. - * - * @param canvas the canvas to paint to - * @param renderer the series renderer - * @param x the x value of the point the shape should be drawn at - * @param y the y value of the point the shape should be drawn at - * @param seriesIndex the series index - * @param paint the paint to be used for drawing - */ - public abstract void drawLegendShape(Canvas canvas, SimpleSeriesRenderer renderer, float x, - float y, int seriesIndex, Paint paint); - - /** - * Calculates the best text to fit into the available space. - * - * @param text the entire text - * @param width the width to fit the text into - * @param paint the paint - * @return the text to fit into the space - */ - private String getFitText(String text, float width, Paint paint) { - String newText = text; - int length = text.length(); - int diff = 0; - while (paint.measureText(newText) > width && diff < length) { - diff++; - newText = text.substring(0, length - diff) + "..."; - } - if (diff == length) { - newText = "..."; - } - return newText; - } - - /** - * Calculates the current legend size. - * - * @param renderer the renderer - * @param defaultHeight the default height - * @param extraHeight the added extra height - * @return the legend size - */ - protected int getLegendSize(DefaultRenderer renderer, int defaultHeight, float extraHeight) { - int legendSize = renderer.getLegendHeight(); - if (renderer.isShowLegend() && legendSize == 0) { - legendSize = defaultHeight; - } - if (!renderer.isShowLegend() && renderer.isShowLabels()) { - legendSize = (int) (renderer.getLabelsTextSize() * 4 / 3 + extraHeight); - } - return legendSize; - } - - /** - * Draws a text label. - * - * @param canvas the canvas - * @param labelText the label text - * @param renderer the renderer - * @param prevLabelsBounds the previous rendered label bounds - * @param centerX the round chart center on X axis - * @param centerY the round chart center on Y axis - * @param shortRadius the short radius for the round chart - * @param longRadius the long radius for the round chart - * @param currentAngle the current angle - * @param angle the label extra angle - * @param left the left side - * @param right the right side - * @param color the label color - * @param paint the paint - * @param line if a line to the label should be drawn - */ - protected void drawLabel(Canvas canvas, String labelText, DefaultRenderer renderer, - List prevLabelsBounds, int centerX, int centerY, float shortRadius, float longRadius, - float currentAngle, float angle, int left, int right, int color, Paint paint, boolean line) { - if (renderer.isShowLabels()) { - paint.setColor(color); - double rAngle = Math.toRadians(90 - (currentAngle + angle / 2)); - double sinValue = Math.sin(rAngle); - double cosValue = Math.cos(rAngle); - int x1 = Math.round(centerX + (float) (shortRadius * sinValue)); - int y1 = Math.round(centerY + (float) (shortRadius * cosValue)); - int x2 = Math.round(centerX + (float) (longRadius * sinValue)); - int y2 = Math.round(centerY + (float) (longRadius * cosValue)); - - float size = renderer.getLabelsTextSize(); - float extra = Math.max(size / 2, 10); - paint.setTextAlign(Align.LEFT); - if (x1 > x2) { - extra = -extra; - paint.setTextAlign(Align.RIGHT); - } - float xLabel = x2 + extra; - float yLabel = y2; - float width = right - xLabel; - if (x1 > x2) { - width = xLabel - left; - } - labelText = getFitText(labelText, width, paint); - float widthLabel = paint.measureText(labelText); - boolean okBounds = false; - while (!okBounds && line) { - boolean intersects = false; - int length = prevLabelsBounds.size(); - for (int j = 0; j < length && !intersects; j++) { - RectF prevLabelBounds = prevLabelsBounds.get(j); - if (prevLabelBounds.intersects(xLabel, yLabel, xLabel + widthLabel, yLabel + size)) { - intersects = true; - yLabel = Math.max(yLabel, prevLabelBounds.bottom); - } - } - okBounds = !intersects; - } - - if (line) { - y2 = (int) (yLabel - size / 2); - canvas.drawLine(x1, y1, x2, y2, paint); - canvas.drawLine(x2, y2, x2 + extra, y2, paint); - } else { - paint.setTextAlign(Align.CENTER); - } - canvas.drawText(labelText, xLabel, yLabel, paint); - if (line) { - prevLabelsBounds.add(new RectF(xLabel, yLabel, xLabel + widthLabel, yLabel + size)); - } - } - } - - public boolean isNullValue(double value) { - return Double.isNaN(value) || Double.isInfinite(value) || value == MathHelper.NULL_VALUE; - } - - /** - * Given screen coordinates, returns the series and point indexes of a chart - * element. If there is no chart element (line, point, bar, etc) at those - * coordinates, null is returned. - * - * @param screenPoint - * @return the series and point indexes - */ - public SeriesSelection getSeriesAndPointForScreenCoordinate(Point screenPoint) { - return null; - } - -} diff --git a/android-libraries/achartengine/src/org/achartengine/chart/BarChart.java b/android-libraries/achartengine/src/org/achartengine/chart/BarChart.java deleted file mode 100644 index d5d0fb235..000000000 --- a/android-libraries/achartengine/src/org/achartengine/chart/BarChart.java +++ /dev/null @@ -1,329 +0,0 @@ -/** - * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.achartengine.chart; - -import org.achartengine.model.XYMultipleSeriesDataset; -import org.achartengine.model.XYSeries; -import org.achartengine.renderer.SimpleSeriesRenderer; -import org.achartengine.renderer.XYMultipleSeriesRenderer; - -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Paint; -import android.graphics.Paint.Style; -import android.graphics.RectF; -import android.graphics.drawable.GradientDrawable; -import android.graphics.drawable.GradientDrawable.Orientation; - -/** - * The bar chart rendering class. - */ -public class BarChart extends XYChart { - /** The constant to identify this chart type. */ - public static final String TYPE = "Bar"; - /** The legend shape width. */ - private static final int SHAPE_WIDTH = 12; - /** The chart type. */ - protected Type mType = Type.DEFAULT; - - /** - * The bar chart type enum. - */ - public enum Type { - DEFAULT, STACKED; - } - - BarChart() { - } - - BarChart(Type type) { - mType = type; - } - - /** - * Builds a new bar chart instance. - * - * @param dataset the multiple series dataset - * @param renderer the multiple series renderer - * @param type the bar chart type - */ - public BarChart(XYMultipleSeriesDataset dataset, XYMultipleSeriesRenderer renderer, Type type) { - super(dataset, renderer); - mType = type; - } - - @Override - protected ClickableArea[] clickableAreasForPoints(float[] points, double[] values, - float yAxisValue, int seriesIndex, int startIndex) { - int seriesNr = mDataset.getSeriesCount(); - int length = points.length; - ClickableArea[] ret = new ClickableArea[length / 2]; - float halfDiffX = getHalfDiffX(points, length, seriesNr); - for (int i = 0; i < length; i += 2) { - float x = points[i]; - float y = points[i + 1]; - if (mType == Type.STACKED) { - ret[i / 2] = new ClickableArea(new RectF(x - halfDiffX, y, x + halfDiffX, yAxisValue), - values[i], values[i + 1]); - } else { - float startX = x - seriesNr * halfDiffX + seriesIndex * 2 * halfDiffX; - ret[i / 2] = new ClickableArea(new RectF(startX, y, startX + 2 * halfDiffX, yAxisValue), - values[i], values[i + 1]); - } - } - return ret; - } - - /** - * The graphical representation of a series. - * - * @param canvas the canvas to paint to - * @param paint the paint to be used for drawing - * @param points the array of points to be used for drawing the series - * @param seriesRenderer the series renderer - * @param yAxisValue the minimum value of the y axis - * @param seriesIndex the index of the series currently being drawn - * @param startIndex the start index of the rendering points - */ - public void drawSeries(Canvas canvas, Paint paint, float[] points, - SimpleSeriesRenderer seriesRenderer, float yAxisValue, int seriesIndex, int startIndex) { - int seriesNr = mDataset.getSeriesCount(); - int length = points.length; - paint.setColor(seriesRenderer.getColor()); - paint.setStyle(Style.FILL); - float halfDiffX = getHalfDiffX(points, length, seriesNr); - for (int i = 0; i < length; i += 2) { - float x = points[i]; - float y = points[i + 1]; - drawBar(canvas, x, yAxisValue, x, y, halfDiffX, seriesNr, seriesIndex, paint); - } - paint.setColor(seriesRenderer.getColor()); - } - - /** - * Draws a bar. - * - * @param canvas the canvas - * @param xMin the X axis minimum - * @param yMin the Y axis minimum - * @param xMax the X axis maximum - * @param yMax the Y axis maximum - * @param halfDiffX half the size of a bar - * @param seriesNr the total number of series - * @param seriesIndex the current series index - * @param paint the paint - */ - protected void drawBar(Canvas canvas, float xMin, float yMin, float xMax, float yMax, - float halfDiffX, int seriesNr, int seriesIndex, Paint paint) { - int scale = mDataset.getSeriesAt(seriesIndex).getScaleNumber(); - if (mType == Type.STACKED) { - drawBar(canvas, xMin - halfDiffX, yMax, xMax + halfDiffX, yMin, scale, seriesIndex, paint); - } else { - float startX = xMin - seriesNr * halfDiffX + seriesIndex * 2 * halfDiffX; - drawBar(canvas, startX, yMax, startX + 2 * halfDiffX, yMin, scale, seriesIndex, paint); - } - } - - /** - * Draws a bar. - * - * @param canvas the canvas - * @param xMin the X axis minimum - * @param yMin the Y axis minimum - * @param xMax the X axis maximum - * @param yMax the Y axis maximum - * @param scale the scale index - * @param seriesIndex the current series index - * @param paint the paint - */ - private void drawBar(Canvas canvas, float xMin, float yMin, float xMax, float yMax, int scale, - int seriesIndex, Paint paint) { - SimpleSeriesRenderer renderer = mRenderer.getSeriesRendererAt(seriesIndex); - if (renderer.isGradientEnabled()) { - float minY = (float) toScreenPoint(new double[] { 0, renderer.getGradientStopValue() }, scale)[1]; - float maxY = (float) toScreenPoint(new double[] { 0, renderer.getGradientStartValue() }, - scale)[1]; - float gradientMinY = Math.max(minY, Math.min(yMin, yMax)); - float gradientMaxY = Math.min(maxY, Math.max(yMin, yMax)); - int gradientMinColor = renderer.getGradientStopColor(); - int gradientMaxColor = renderer.getGradientStartColor(); - int gradientStartColor = gradientMaxColor; - int gradientStopColor = gradientMinColor; - - if (yMin < minY) { - paint.setColor(gradientMinColor); - canvas.drawRect(Math.round(xMin), Math.round(yMin), Math.round(xMax), - Math.round(gradientMinY), paint); - } else { - gradientStopColor = getGradientPartialColor(gradientMinColor, gradientMaxColor, - (maxY - gradientMinY) / (maxY - minY)); - } - if (yMax > maxY) { - paint.setColor(gradientMaxColor); - canvas.drawRect(Math.round(xMin), Math.round(gradientMaxY), Math.round(xMax), - Math.round(yMax), paint); - } else { - gradientStartColor = getGradientPartialColor(gradientMaxColor, gradientMinColor, - (gradientMaxY - minY) / (maxY - minY)); - } - GradientDrawable gradient = new GradientDrawable(Orientation.BOTTOM_TOP, new int[] { - gradientStartColor, gradientStopColor }); - gradient.setBounds(Math.round(xMin), Math.round(gradientMinY), Math.round(xMax), - Math.round(gradientMaxY)); - gradient.draw(canvas); - } else { - if (Math.abs(yMin - yMax) < 1) { - if (yMin < yMax) { - yMax = yMin + 1; - } else { - yMax = yMin - 1; - } - } - canvas - .drawRect(Math.round(xMin), Math.round(yMin), Math.round(xMax), Math.round(yMax), paint); - } - } - - private int getGradientPartialColor(int minColor, int maxColor, float fraction) { - int alpha = Math.round(fraction * Color.alpha(minColor) + (1 - fraction) - * Color.alpha(maxColor)); - int r = Math.round(fraction * Color.red(minColor) + (1 - fraction) * Color.red(maxColor)); - int g = Math.round(fraction * Color.green(minColor) + (1 - fraction) * Color.green(maxColor)); - int b = Math.round(fraction * Color.blue(minColor) + (1 - fraction) * Color.blue((maxColor))); - return Color.argb(alpha, r, g, b); - } - - /** - * The graphical representation of the series values as text. - * - * @param canvas the canvas to paint to - * @param series the series to be painted - * @param renderer the series renderer - * @param paint the paint to be used for drawing - * @param points the array of points to be used for drawing the series - * @param seriesIndex the index of the series currently being drawn - * @param startIndex the start index of the rendering points - */ - protected void drawChartValuesText(Canvas canvas, XYSeries series, SimpleSeriesRenderer renderer, - Paint paint, float[] points, int seriesIndex, int startIndex) { - int seriesNr = mDataset.getSeriesCount(); - float halfDiffX = getHalfDiffX(points, points.length, seriesNr); - for (int i = 0; i < points.length; i += 2) { - int index = startIndex + i / 2; - double value = series.getY(index); - if (!isNullValue(value)) { - float x = points[i]; - if (mType == Type.DEFAULT) { - x += seriesIndex * 2 * halfDiffX - (seriesNr - 1.5f) * halfDiffX; - } - if (value >= 0) { - drawText(canvas, getLabel(value), x, points[i + 1] - renderer.getChartValuesSpacing(), - paint, 0); - } else { - drawText(canvas, getLabel(value), x, points[i + 1] + renderer.getChartValuesTextSize() - + renderer.getChartValuesSpacing() - 3, paint, 0); - } - } - } - } - - /** - * Returns the legend shape width. - * - * @param seriesIndex the series index - * @return the legend shape width - */ - public int getLegendShapeWidth(int seriesIndex) { - return SHAPE_WIDTH; - } - - /** - * The graphical representation of the legend shape. - * - * @param canvas the canvas to paint to - * @param renderer the series renderer - * @param x the x value of the point the shape should be drawn at - * @param y the y value of the point the shape should be drawn at - * @param seriesIndex the series index - * @param paint the paint to be used for drawing - */ - public void drawLegendShape(Canvas canvas, SimpleSeriesRenderer renderer, float x, float y, - int seriesIndex, Paint paint) { - float halfShapeWidth = SHAPE_WIDTH / 2; - canvas.drawRect(x, y - halfShapeWidth, x + SHAPE_WIDTH, y + halfShapeWidth, paint); - } - - /** - * Calculates and returns the half-distance in the graphical representation of - * 2 consecutive points. - * - * @param points the points - * @param length the points length - * @param seriesNr the series number - * @return the calculated half-distance value - */ - protected float getHalfDiffX(float[] points, int length, int seriesNr) { - int div = length; - if (length > 2) { - div = length - 2; - } - float halfDiffX = (points[length - 2] - points[0]) / div; - if (halfDiffX == 0) { - halfDiffX = 10; - } - - if (mType != Type.STACKED) { - halfDiffX /= seriesNr; - } - return (float) (halfDiffX / (getCoeficient() * (1 + mRenderer.getBarSpacing()))); - } - - /** - * Returns the value of a constant used to calculate the half-distance. - * - * @return the constant value - */ - protected float getCoeficient() { - return 1f; - } - - /** - * Returns if the chart should display the null values. - * - * @return if null values should be rendered - */ - protected boolean isRenderNullValues() { - return true; - } - - /** - * Returns the default axis minimum. - * - * @return the default axis minimum - */ - public double getDefaultMinimum() { - return 0; - } - - /** - * Returns the chart type identifier. - * - * @return the chart type - */ - public String getChartType() { - return TYPE; - } -} diff --git a/android-libraries/achartengine/src/org/achartengine/chart/BubbleChart.java b/android-libraries/achartengine/src/org/achartengine/chart/BubbleChart.java deleted file mode 100644 index f3125713b..000000000 --- a/android-libraries/achartengine/src/org/achartengine/chart/BubbleChart.java +++ /dev/null @@ -1,146 +0,0 @@ -/** - * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.achartengine.chart; - -import org.achartengine.model.XYMultipleSeriesDataset; -import org.achartengine.model.XYValueSeries; -import org.achartengine.renderer.SimpleSeriesRenderer; -import org.achartengine.renderer.XYMultipleSeriesRenderer; -import org.achartengine.renderer.XYSeriesRenderer; - -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.Paint.Style; -import android.graphics.RectF; - -/** - * The bubble chart rendering class. - */ -public class BubbleChart extends XYChart { - /** The constant to identify this chart type. */ - public static final String TYPE = "Bubble"; - /** The legend shape width. */ - private static final int SHAPE_WIDTH = 10; - /** The minimum bubble size. */ - private static final int MIN_BUBBLE_SIZE = 2; - /** The maximum bubble size. */ - private static final int MAX_BUBBLE_SIZE = 20; - - BubbleChart() { - } - - /** - * Builds a new bubble chart instance. - * - * @param dataset the multiple series dataset - * @param renderer the multiple series renderer - */ - public BubbleChart(XYMultipleSeriesDataset dataset, XYMultipleSeriesRenderer renderer) { - super(dataset, renderer); - } - - /** - * The graphical representation of a series. - * - * @param canvas the canvas to paint to - * @param paint the paint to be used for drawing - * @param points the array of points to be used for drawing the series - * @param seriesRenderer the series renderer - * @param yAxisValue the minimum value of the y axis - * @param seriesIndex the index of the series currently being drawn - * @param startIndex the start index of the rendering points - */ - public void drawSeries(Canvas canvas, Paint paint, float[] points, - SimpleSeriesRenderer seriesRenderer, float yAxisValue, int seriesIndex, int startIndex) { - XYSeriesRenderer renderer = (XYSeriesRenderer) seriesRenderer; - paint.setColor(renderer.getColor()); - paint.setStyle(Style.FILL); - int length = points.length; - XYValueSeries series = (XYValueSeries) mDataset.getSeriesAt(seriesIndex); - double max = series.getMaxValue(); - double coef = MAX_BUBBLE_SIZE / max; - for (int i = 0; i < length; i += 2) { - double size = series.getValue(startIndex + i / 2) * coef + MIN_BUBBLE_SIZE; - drawCircle(canvas, paint, points[i], points[i + 1], (float) size); - } - } - - @Override - protected ClickableArea[] clickableAreasForPoints(float[] points, double[] values, - float yAxisValue, int seriesIndex, int startIndex) { - int length = points.length; - XYValueSeries series = (XYValueSeries) mDataset.getSeriesAt(seriesIndex); - double max = series.getMaxValue(); - double coef = MAX_BUBBLE_SIZE / max; - ClickableArea[] ret = new ClickableArea[length / 2]; - for (int i = 0; i < length; i += 2) { - double size = series.getValue(startIndex + i / 2) * coef + MIN_BUBBLE_SIZE; - ret[i / 2] = new ClickableArea(new RectF(points[i] - (float) size, points[i + 1] - - (float) size, points[i] + (float) size, points[i + 1] + (float) size), values[i], - values[i + 1]); - } - return ret; - } - - /** - * Returns the legend shape width. - * - * @param seriesIndex the series index - * @return the legend shape width - */ - public int getLegendShapeWidth(int seriesIndex) { - return SHAPE_WIDTH; - } - - /** - * The graphical representation of the legend shape. - * - * @param canvas the canvas to paint to - * @param renderer the series renderer - * @param x the x value of the point the shape should be drawn at - * @param y the y value of the point the shape should be drawn at - * @param seriesIndex the series index - * @param paint the paint to be used for drawing - */ - public void drawLegendShape(Canvas canvas, SimpleSeriesRenderer renderer, float x, float y, - int seriesIndex, Paint paint) { - paint.setStyle(Style.FILL); - drawCircle(canvas, paint, x + SHAPE_WIDTH, y, 3); - } - - /** - * The graphical representation of a circle point shape. - * - * @param canvas the canvas to paint to - * @param paint the paint to be used for drawing - * @param x the x value of the point the shape should be drawn at - * @param y the y value of the point the shape should be drawn at - * @param radius the bubble radius - */ - private void drawCircle(Canvas canvas, Paint paint, float x, float y, float radius) { - canvas.drawCircle(x, y, radius, paint); - } - - /** - * Returns the chart type identifier. - * - * @return the chart type - */ - public String getChartType() { - return TYPE; - } - -} \ No newline at end of file diff --git a/android-libraries/achartengine/src/org/achartengine/chart/ClickableArea.java b/android-libraries/achartengine/src/org/achartengine/chart/ClickableArea.java deleted file mode 100644 index d2d306ca0..000000000 --- a/android-libraries/achartengine/src/org/achartengine/chart/ClickableArea.java +++ /dev/null @@ -1,44 +0,0 @@ -/** - * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.achartengine.chart; - -import android.graphics.RectF; - -public class ClickableArea { - private RectF rect; - private double x; - private double y; - - public ClickableArea(RectF rect, double x, double y) { - super(); - this.rect = rect; - this.x = x; - this.y = y; - } - - public RectF getRect() { - return rect; - } - - public double getX() { - return x; - } - - public double getY() { - return y; - } - -} diff --git a/android-libraries/achartengine/src/org/achartengine/chart/CombinedXYChart.java b/android-libraries/achartengine/src/org/achartengine/chart/CombinedXYChart.java deleted file mode 100644 index d684c3a2a..000000000 --- a/android-libraries/achartengine/src/org/achartengine/chart/CombinedXYChart.java +++ /dev/null @@ -1,177 +0,0 @@ -/** - * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.achartengine.chart; - -import java.util.List; - -import org.achartengine.model.XYMultipleSeriesDataset; -import org.achartengine.model.XYSeries; -import org.achartengine.renderer.SimpleSeriesRenderer; -import org.achartengine.renderer.XYMultipleSeriesRenderer; -import org.achartengine.renderer.XYMultipleSeriesRenderer.Orientation; - -import android.graphics.Canvas; -import android.graphics.Paint; - -/** - * The combined XY chart rendering class. - */ -public class CombinedXYChart extends XYChart { - /** The embedded XY charts. */ - private XYChart[] mCharts; - /** The supported charts for being combined. */ - private Class[] xyChartTypes = new Class[] { TimeChart.class, LineChart.class, - CubicLineChart.class, BarChart.class, BubbleChart.class, ScatterChart.class, - RangeBarChart.class, RangeStackedBarChart.class }; - - /** - * Builds a new combined XY chart instance. - * - * @param dataset the multiple series dataset - * @param renderer the multiple series renderer - * @param types the XY chart types - */ - public CombinedXYChart(XYMultipleSeriesDataset dataset, XYMultipleSeriesRenderer renderer, - String[] types) { - super(dataset, renderer); - int length = types.length; - mCharts = new XYChart[length]; - for (int i = 0; i < length; i++) { - try { - mCharts[i] = getXYChart(types[i]); - } catch (Exception e) { - // ignore - } - if (mCharts[i] == null) { - throw new IllegalArgumentException("Unknown chart type " + types[i]); - } else { - XYMultipleSeriesDataset newDataset = new XYMultipleSeriesDataset(); - newDataset.addSeries(dataset.getSeriesAt(i)); - XYMultipleSeriesRenderer newRenderer = new XYMultipleSeriesRenderer(); - // TODO: copy other parameters here - newRenderer.setBarSpacing(renderer.getBarSpacing()); - newRenderer.setPointSize(renderer.getPointSize()); - int scale = dataset.getSeriesAt(i).getScaleNumber(); - if (renderer.isMinXSet(scale)) { - newRenderer.setXAxisMin(renderer.getXAxisMin(scale)); - } - if (renderer.isMaxXSet(scale)) { - newRenderer.setXAxisMax(renderer.getXAxisMax(scale)); - } - if (renderer.isMinYSet(scale)) { - newRenderer.setYAxisMin(renderer.getYAxisMin(scale)); - } - if (renderer.isMaxYSet(scale)) { - newRenderer.setYAxisMax(renderer.getYAxisMax(scale)); - } - newRenderer.addSeriesRenderer(renderer.getSeriesRendererAt(i)); - mCharts[i].setDatasetRenderer(newDataset, newRenderer); - } - } - } - - /** - * Returns a chart instance based on the provided type. - * - * @param type the chart type - * @return an instance of a chart implementation - * @throws IllegalAccessException - * @throws InstantiationException - */ - private XYChart getXYChart(String type) throws IllegalAccessException, InstantiationException { - XYChart chart = null; - int length = xyChartTypes.length; - for (int i = 0; i < length && chart == null; i++) { - XYChart newChart = (XYChart) xyChartTypes[i].newInstance(); - if (type.equals(newChart.getChartType())) { - chart = newChart; - } - } - return chart; - } - - /** - * The graphical representation of a series. - * - * @param canvas the canvas to paint to - * @param paint the paint to be used for drawing - * @param points the array of points to be used for drawing the series - * @param seriesRenderer the series renderer - * @param yAxisValue the minimum value of the y axis - * @param seriesIndex the index of the series currently being drawn - * @param startIndex the start index of the rendering points - */ - public void drawSeries(Canvas canvas, Paint paint, float[] points, - SimpleSeriesRenderer seriesRenderer, float yAxisValue, int seriesIndex, int startIndex) { - mCharts[seriesIndex].setScreenR(getScreenR()); - mCharts[seriesIndex].setCalcRange(getCalcRange(mDataset.getSeriesAt(seriesIndex) - .getScaleNumber()), 0); - mCharts[seriesIndex].drawSeries(canvas, paint, points, seriesRenderer, yAxisValue, 0, - startIndex); - } - - @Override - protected ClickableArea[] clickableAreasForPoints(float[] points, double[] values, - float yAxisValue, int seriesIndex, int startIndex) { - return mCharts[seriesIndex].clickableAreasForPoints(points, values, yAxisValue, 0, startIndex); - } - - @Override - protected void drawSeries(XYSeries series, Canvas canvas, Paint paint, List pointsList, - SimpleSeriesRenderer seriesRenderer, float yAxisValue, int seriesIndex, Orientation or, - int startIndex) { - mCharts[seriesIndex].setScreenR(getScreenR()); - mCharts[seriesIndex].setCalcRange(getCalcRange(mDataset.getSeriesAt(seriesIndex) - .getScaleNumber()), 0); - mCharts[seriesIndex].drawSeries(series, canvas, paint, pointsList, seriesRenderer, yAxisValue, - 0, or, startIndex); - } - - /** - * Returns the legend shape width. - * - * @param seriesIndex the series index - * @return the legend shape width - */ - public int getLegendShapeWidth(int seriesIndex) { - return mCharts[seriesIndex].getLegendShapeWidth(0); - } - - /** - * The graphical representation of the legend shape. - * - * @param canvas the canvas to paint to - * @param renderer the series renderer - * @param x the x value of the point the shape should be drawn at - * @param y the y value of the point the shape should be drawn at - * @param seriesIndex the series index - * @param paint the paint to be used for drawing - */ - public void drawLegendShape(Canvas canvas, SimpleSeriesRenderer renderer, float x, float y, - int seriesIndex, Paint paint) { - mCharts[seriesIndex].drawLegendShape(canvas, renderer, x, y, 0, paint); - } - - /** - * Returns the chart type identifier. - * - * @return the chart type - */ - public String getChartType() { - return "Combined"; - } - -} diff --git a/android-libraries/achartengine/src/org/achartengine/chart/CubicLineChart.java b/android-libraries/achartengine/src/org/achartengine/chart/CubicLineChart.java deleted file mode 100644 index 2011318f5..000000000 --- a/android-libraries/achartengine/src/org/achartengine/chart/CubicLineChart.java +++ /dev/null @@ -1,120 +0,0 @@ -/** - * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.achartengine.chart; - -import org.achartengine.model.Point; -import org.achartengine.model.XYMultipleSeriesDataset; -import org.achartengine.renderer.XYMultipleSeriesRenderer; - -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.Path; - -/** - * The interpolated (cubic) line chart rendering class. - */ -public class CubicLineChart extends LineChart { - /** The chart type. */ - public static final String TYPE = "Cubic"; - - private float firstMultiplier; - - private float secondMultiplier; - - private Point p1 = new Point(); - - private Point p2 = new Point(); - - private Point p3 = new Point(); - - public CubicLineChart() { - // default is to have first control point at about 33% of the distance, - firstMultiplier = 0.33f; - // and the next at 66% of the distance. - secondMultiplier = 1 - firstMultiplier; - } - - /** - * Builds a cubic line chart. - * - * @param dataset the dataset - * @param renderer the renderer - * @param smoothness smoothness determines how smooth the curve should be, - * range [0->0.5] super smooth, 0.5, means that it might not get - * close to control points if you have random data // less smooth, - * (close to 0) means that it will most likely touch all control // - * points - */ - public CubicLineChart(XYMultipleSeriesDataset dataset, XYMultipleSeriesRenderer renderer, - float smoothness) { - super(dataset, renderer); - firstMultiplier = smoothness; - secondMultiplier = 1 - firstMultiplier; - } - - @Override - protected void drawPath(Canvas canvas, float[] points, Paint paint, boolean circular) { - Path p = new Path(); - float x = points[0]; - float y = points[1]; - p.moveTo(x, y); - - int length = points.length; - if (circular) { - length -= 4; - } - - for (int i = 0; i < length; i += 2) { - int nextIndex = i + 2 < length ? i + 2 : i; - int nextNextIndex = i + 4 < length ? i + 4 : nextIndex; - calc(points, p1, i, nextIndex, secondMultiplier); - p2.setX(points[nextIndex]); - p2.setY(points[nextIndex + 1]); - calc(points, p3, nextIndex, nextNextIndex, firstMultiplier); - // From last point, approaching x1/y1 and x2/y2 and ends up at x3/y3 - p.cubicTo(p1.getX(), p1.getY(), p2.getX(), p2.getY(), p3.getX(), p3.getY()); - } - if (circular) { - for (int i = length; i < length + 4; i += 2) { - p.lineTo(points[i], points[i + 1]); - } - p.lineTo(points[0], points[1]); - } - canvas.drawPath(p, paint); - } - - private void calc(float[] points, Point result, int index1, int index2, final float multiplier) { - float p1x = points[index1]; - float p1y = points[index1 + 1]; - float p2x = points[index2]; - float p2y = points[index2 + 1]; - - float diffX = p2x - p1x; // p2.x - p1.x; - float diffY = p2y - p1y; // p2.y - p1.y; - result.setX(p1x + (diffX * multiplier)); - result.setY(p1y + (diffY * multiplier)); - } - - /** - * Returns the chart type identifier. - * - * @return the chart type - */ - public String getChartType() { - return TYPE; - } - -} diff --git a/android-libraries/achartengine/src/org/achartengine/chart/DialChart.java b/android-libraries/achartengine/src/org/achartengine/chart/DialChart.java deleted file mode 100644 index ebfcbbb1f..000000000 --- a/android-libraries/achartengine/src/org/achartengine/chart/DialChart.java +++ /dev/null @@ -1,236 +0,0 @@ -/** - * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.achartengine.chart; - -import org.achartengine.model.CategorySeries; -import org.achartengine.renderer.DefaultRenderer; -import org.achartengine.renderer.DialRenderer; -import org.achartengine.renderer.DialRenderer.Type; -import org.achartengine.util.MathHelper; - -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.Paint.Align; -import android.graphics.Paint.Style; - -/** - * The dial chart rendering class. - */ -public class DialChart extends RoundChart { - /** The radius of the needle. */ - private static final int NEEDLE_RADIUS = 10; - /** The series renderer. */ - private DialRenderer mRenderer; - - /** - * Builds a new dial chart instance. - * - * @param dataset the series dataset - * @param renderer the dial renderer - */ - public DialChart(CategorySeries dataset, DialRenderer renderer) { - super(dataset, renderer); - mRenderer = renderer; - } - - /** - * The graphical representation of the dial chart. - * - * @param canvas the canvas to paint to - * @param x the top left x value of the view to draw to - * @param y the top left y value of the view to draw to - * @param width the width of the view to draw to - * @param height the height of the view to draw to - * @param paint the paint - */ - @Override - public void draw(Canvas canvas, int x, int y, int width, int height, Paint paint) { - paint.setAntiAlias(mRenderer.isAntialiasing()); - paint.setStyle(Style.FILL); - paint.setTextSize(mRenderer.getLabelsTextSize()); - int legendSize = getLegendSize(mRenderer, height / 5, 0); - int left = x; - int top = y; - int right = x + width; - - int sLength = mDataset.getItemCount(); - String[] titles = new String[sLength]; - for (int i = 0; i < sLength; i++) { - titles[i] = mDataset.getCategory(i); - } - - if (mRenderer.isFitLegend()) { - legendSize = drawLegend(canvas, mRenderer, titles, left, right, y, width, height, legendSize, - paint, true); - } - int bottom = y + height - legendSize; - drawBackground(mRenderer, canvas, x, y, width, height, paint, false, DefaultRenderer.NO_COLOR); - - int mRadius = Math.min(Math.abs(right - left), Math.abs(bottom - top)); - int radius = (int) (mRadius * 0.35 * mRenderer.getScale()); - if (mCenterX == NO_VALUE) { - mCenterX = (left + right) / 2; - } - if (mCenterY == NO_VALUE) { - mCenterY = (bottom + top) / 2; - } - float shortRadius = radius * 0.9f; - float longRadius = radius * 1.1f; - double min = mRenderer.getMinValue(); - double max = mRenderer.getMaxValue(); - double angleMin = mRenderer.getAngleMin(); - double angleMax = mRenderer.getAngleMax(); - if (!mRenderer.isMinValueSet() || !mRenderer.isMaxValueSet()) { - int count = mRenderer.getSeriesRendererCount(); - for (int i = 0; i < count; i++) { - double value = mDataset.getValue(i); - if (!mRenderer.isMinValueSet()) { - min = Math.min(min, value); - } - if (!mRenderer.isMaxValueSet()) { - max = Math.max(max, value); - } - } - } - if (min == max) { - min = min * 0.5; - max = max * 1.5; - } - - paint.setColor(mRenderer.getLabelsColor()); - double minorTicks = mRenderer.getMinorTicksSpacing(); - double majorTicks = mRenderer.getMajorTicksSpacing(); - if (minorTicks == MathHelper.NULL_VALUE) { - minorTicks = (max - min) / 30; - } - if (majorTicks == MathHelper.NULL_VALUE) { - majorTicks = (max - min) / 10; - } - drawTicks(canvas, min, max, angleMin, angleMax, mCenterX, mCenterY, longRadius, radius, - minorTicks, paint, false); - drawTicks(canvas, min, max, angleMin, angleMax, mCenterX, mCenterY, longRadius, shortRadius, - majorTicks, paint, true); - - int count = mRenderer.getSeriesRendererCount(); - for (int i = 0; i < count; i++) { - double angle = getAngleForValue(mDataset.getValue(i), angleMin, angleMax, min, max); - paint.setColor(mRenderer.getSeriesRendererAt(i).getColor()); - boolean type = mRenderer.getVisualTypeForIndex(i) == Type.ARROW; - drawNeedle(canvas, angle, mCenterX, mCenterY, shortRadius, type, paint); - } - drawLegend(canvas, mRenderer, titles, left, right, y, width, height, legendSize, paint, false); - drawTitle(canvas, x, y, width, paint); - } - - /** - * Returns the angle for a specific chart value. - * - * @param value the chart value - * @param minAngle the minimum chart angle value - * @param maxAngle the maximum chart angle value - * @param min the minimum chart value - * @param max the maximum chart value - * @return the angle - */ - private double getAngleForValue(double value, double minAngle, double maxAngle, double min, - double max) { - double angleDiff = maxAngle - minAngle; - double diff = max - min; - return Math.toRadians(minAngle + (value - min) * angleDiff / diff); - } - - /** - * Draws the chart tick lines. - * - * @param canvas the canvas - * @param min the minimum chart value - * @param max the maximum chart value - * @param minAngle the minimum chart angle value - * @param maxAngle the maximum chart angle value - * @param centerX the center x value - * @param centerY the center y value - * @param longRadius the long radius - * @param shortRadius the short radius - * @param ticks the tick spacing - * @param paint the paint settings - * @param labels paint the labels - * @return the angle - */ - private void drawTicks(Canvas canvas, double min, double max, double minAngle, double maxAngle, - int centerX, int centerY, double longRadius, double shortRadius, double ticks, Paint paint, - boolean labels) { - for (double i = min; i <= max; i += ticks) { - double angle = getAngleForValue(i, minAngle, maxAngle, min, max); - double sinValue = Math.sin(angle); - double cosValue = Math.cos(angle); - int x1 = Math.round(centerX + (float) (shortRadius * sinValue)); - int y1 = Math.round(centerY + (float) (shortRadius * cosValue)); - int x2 = Math.round(centerX + (float) (longRadius * sinValue)); - int y2 = Math.round(centerY + (float) (longRadius * cosValue)); - canvas.drawLine(x1, y1, x2, y2, paint); - if (labels) { - paint.setTextAlign(Align.LEFT); - if (x1 <= x2) { - paint.setTextAlign(Align.RIGHT); - } - String text = i + ""; - if (Math.round(i) == (long) i) { - text = (long) i + ""; - } - canvas.drawText(text, x1, y1, paint); - } - } - } - - /** - * Returns the angle for a specific chart value. - * - * @param canvas the canvas - * @param angle the needle angle value - * @param centerX the center x value - * @param centerY the center y value - * @param radius the radius - * @param arrow if a needle or an arrow to be painted - * @param paint the paint settings - * @return the angle - */ - private void drawNeedle(Canvas canvas, double angle, int centerX, int centerY, double radius, - boolean arrow, Paint paint) { - double diff = Math.toRadians(90); - int needleSinValue = (int) (NEEDLE_RADIUS * Math.sin(angle - diff)); - int needleCosValue = (int) (NEEDLE_RADIUS * Math.cos(angle - diff)); - int needleX = (int) (radius * Math.sin(angle)); - int needleY = (int) (radius * Math.cos(angle)); - int needleCenterX = centerX + needleX; - int needleCenterY = centerY + needleY; - float[] points; - if (arrow) { - int arrowBaseX = centerX + (int) (radius * 0.85 * Math.sin(angle)); - int arrowBaseY = centerY + (int) (radius * 0.85 * Math.cos(angle)); - points = new float[] { arrowBaseX - needleSinValue, arrowBaseY - needleCosValue, - needleCenterX, needleCenterY, arrowBaseX + needleSinValue, arrowBaseY + needleCosValue }; - float width = paint.getStrokeWidth(); - paint.setStrokeWidth(5); - canvas.drawLine(centerX, centerY, needleCenterX, needleCenterY, paint); - paint.setStrokeWidth(width); - } else { - points = new float[] { centerX - needleSinValue, centerY - needleCosValue, needleCenterX, - needleCenterY, centerX + needleSinValue, centerY + needleCosValue }; - } - drawPath(canvas, points, paint, true); - } - -} diff --git a/android-libraries/achartengine/src/org/achartengine/chart/DoughnutChart.java b/android-libraries/achartengine/src/org/achartengine/chart/DoughnutChart.java deleted file mode 100644 index ad67b0769..000000000 --- a/android-libraries/achartengine/src/org/achartengine/chart/DoughnutChart.java +++ /dev/null @@ -1,162 +0,0 @@ -/** - * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.achartengine.chart; - -import java.util.ArrayList; -import java.util.List; - -import org.achartengine.model.MultipleCategorySeries; -import org.achartengine.renderer.DefaultRenderer; -import org.achartengine.renderer.SimpleSeriesRenderer; - -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Paint; -import android.graphics.Paint.Style; -import android.graphics.RectF; - -/** - * The doughnut chart rendering class. - */ -public class DoughnutChart extends RoundChart { - /** The series dataset. */ - private MultipleCategorySeries mDataset; - /** A step variable to control the size of the legend shape. */ - private int mStep; - - /** - * Builds a new doughnut chart instance. - * - * @param dataset the series dataset - * @param renderer the series renderer - */ - public DoughnutChart(MultipleCategorySeries dataset, DefaultRenderer renderer) { - super(null, renderer); - mDataset = dataset; - } - - /** - * The graphical representation of the doughnut chart. - * - * @param canvas the canvas to paint to - * @param x the top left x value of the view to draw to - * @param y the top left y value of the view to draw to - * @param width the width of the view to draw to - * @param height the height of the view to draw to - * @param paint the paint - */ - @Override - public void draw(Canvas canvas, int x, int y, int width, int height, Paint paint) { - paint.setAntiAlias(mRenderer.isAntialiasing()); - paint.setStyle(Style.FILL); - paint.setTextSize(mRenderer.getLabelsTextSize()); - int legendSize = getLegendSize(mRenderer, height / 5, 0); - int left = x; - int top = y; - int right = x + width; - int cLength = mDataset.getCategoriesCount(); - String[] categories = new String[cLength]; - for (int category = 0; category < cLength; category++) { - categories[category] = mDataset.getCategory(category); - } - if (mRenderer.isFitLegend()) { - legendSize = drawLegend(canvas, mRenderer, categories, left, right, y, width, height, - legendSize, paint, true); - } - - int bottom = y + height - legendSize; - drawBackground(mRenderer, canvas, x, y, width, height, paint, false, DefaultRenderer.NO_COLOR); - mStep = SHAPE_WIDTH * 3 / 4; - - int mRadius = Math.min(Math.abs(right - left), Math.abs(bottom - top)); - double rCoef = 0.35 * mRenderer.getScale(); - double decCoef = 0.2 / cLength; - int radius = (int) (mRadius * rCoef); - if (mCenterX == NO_VALUE) { - mCenterX = (left + right) / 2; - } - if (mCenterY == NO_VALUE) { - mCenterY = (bottom + top) / 2; - } - float shortRadius = radius * 0.9f; - float longRadius = radius * 1.1f; - List prevLabelsBounds = new ArrayList(); - for (int category = 0; category < cLength; category++) { - int sLength = mDataset.getItemCount(category); - double total = 0; - String[] titles = new String[sLength]; - for (int i = 0; i < sLength; i++) { - total += mDataset.getValues(category)[i]; - titles[i] = mDataset.getTitles(category)[i]; - } - float currentAngle = mRenderer.getStartAngle(); - RectF oval = new RectF(mCenterX - radius, mCenterY - radius, mCenterX + radius, mCenterY - + radius); - for (int i = 0; i < sLength; i++) { - paint.setColor(mRenderer.getSeriesRendererAt(i).getColor()); - float value = (float) mDataset.getValues(category)[i]; - float angle = (float) (value / total * 360); - canvas.drawArc(oval, currentAngle, angle, true, paint); - drawLabel(canvas, mDataset.getTitles(category)[i], mRenderer, prevLabelsBounds, mCenterX, - mCenterY, shortRadius, longRadius, currentAngle, angle, left, right, - mRenderer.getLabelsColor(), paint, true); - currentAngle += angle; - } - radius -= (int) mRadius * decCoef; - shortRadius -= mRadius * decCoef - 2; - if (mRenderer.getBackgroundColor() != 0) { - paint.setColor(mRenderer.getBackgroundColor()); - } else { - paint.setColor(Color.WHITE); - } - paint.setStyle(Style.FILL); - oval = new RectF(mCenterX - radius, mCenterY - radius, mCenterX + radius, mCenterY + radius); - canvas.drawArc(oval, 0, 360, true, paint); - radius -= 1; - } - prevLabelsBounds.clear(); - drawLegend(canvas, mRenderer, categories, left, right, y, width, height, legendSize, paint, - false); - drawTitle(canvas, x, y, width, paint); - } - - /** - * Returns the legend shape width. - * - * @param seriesIndex the series index - * @return the legend shape width - */ - public int getLegendShapeWidth(int seriesIndex) { - return SHAPE_WIDTH; - } - - /** - * The graphical representation of the legend shape. - * - * @param canvas the canvas to paint to - * @param renderer the series renderer - * @param x the x value of the point the shape should be drawn at - * @param y the y value of the point the shape should be drawn at - * @param seriesIndex the series index - * @param paint the paint to be used for drawing - */ - public void drawLegendShape(Canvas canvas, SimpleSeriesRenderer renderer, float x, float y, - int seriesIndex, Paint paint) { - mStep--; - canvas.drawCircle(x + SHAPE_WIDTH - mStep, y, mStep, paint); - } - -} diff --git a/android-libraries/achartengine/src/org/achartengine/chart/LineChart.java b/android-libraries/achartengine/src/org/achartengine/chart/LineChart.java deleted file mode 100644 index 2c4589863..000000000 --- a/android-libraries/achartengine/src/org/achartengine/chart/LineChart.java +++ /dev/null @@ -1,175 +0,0 @@ -/** - * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.achartengine.chart; - -import org.achartengine.model.XYMultipleSeriesDataset; -import org.achartengine.renderer.SimpleSeriesRenderer; -import org.achartengine.renderer.XYMultipleSeriesRenderer; -import org.achartengine.renderer.XYSeriesRenderer; - -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.Paint.Style; -import android.graphics.RectF; - -/** - * The line chart rendering class. - */ -public class LineChart extends XYChart { - /** The constant to identify this chart type. */ - public static final String TYPE = "Line"; - /** The legend shape width. */ - private static final int SHAPE_WIDTH = 30; - /** The scatter chart to be used to draw the data points. */ - private ScatterChart pointsChart; - - LineChart() { - } - - /** - * Builds a new line chart instance. - * - * @param dataset the multiple series dataset - * @param renderer the multiple series renderer - */ - public LineChart(XYMultipleSeriesDataset dataset, XYMultipleSeriesRenderer renderer) { - super(dataset, renderer); - pointsChart = new ScatterChart(dataset, renderer); - } - - /** - * Sets the series and the renderer. - * - * @param dataset the series dataset - * @param renderer the series renderer - */ - protected void setDatasetRenderer(XYMultipleSeriesDataset dataset, - XYMultipleSeriesRenderer renderer) { - super.setDatasetRenderer(dataset, renderer); - pointsChart = new ScatterChart(dataset, renderer); - } - - /** - * The graphical representation of a series. - * - * @param canvas the canvas to paint to - * @param paint the paint to be used for drawing - * @param points the array of points to be used for drawing the series - * @param seriesRenderer the series renderer - * @param yAxisValue the minimum value of the y axis - * @param seriesIndex the index of the series currently being drawn - * @param startIndex the start index of the rendering points - */ - public void drawSeries(Canvas canvas, Paint paint, float[] points, - SimpleSeriesRenderer seriesRenderer, float yAxisValue, int seriesIndex, int startIndex) { - int length = points.length; - XYSeriesRenderer renderer = (XYSeriesRenderer) seriesRenderer; - float lineWidth = paint.getStrokeWidth(); - paint.setStrokeWidth(renderer.getLineWidth()); - if (renderer.isFillBelowLine()) { - paint.setColor(renderer.getFillBelowLineColor()); - int pLength = points.length; - float[] fillPoints = new float[pLength + 4]; - System.arraycopy(points, 0, fillPoints, 0, length); - fillPoints[0] = points[0] + 1; - fillPoints[length] = fillPoints[length - 2]; - fillPoints[length + 1] = yAxisValue; - fillPoints[length + 2] = fillPoints[0]; - fillPoints[length + 3] = fillPoints[length + 1]; - for (int i = 0; i < length + 4; i += 2) { - if (fillPoints[i + 1] < 0) { - fillPoints[i + 1] = 0; - } - } - paint.setStyle(Style.FILL); - drawPath(canvas, fillPoints, paint, true); - } - paint.setColor(seriesRenderer.getColor()); - paint.setStyle(Style.STROKE); - drawPath(canvas, points, paint, false); - paint.setStrokeWidth(lineWidth); - } - - @Override - protected ClickableArea[] clickableAreasForPoints(float[] points, double[] values, - float yAxisValue, int seriesIndex, int startIndex) { - int length = points.length; - ClickableArea[] ret = new ClickableArea[length / 2]; - for (int i = 0; i < length; i += 2) { - int selectableBuffer = mRenderer.getSelectableBuffer(); - ret[i / 2] = new ClickableArea(new RectF(points[i] - selectableBuffer, points[i + 1] - - selectableBuffer, points[i] + selectableBuffer, points[i + 1] + selectableBuffer), - values[i], values[i + 1]); - } - return ret; - } - - /** - * Returns the legend shape width. - * - * @param seriesIndex the series index - * @return the legend shape width - */ - public int getLegendShapeWidth(int seriesIndex) { - return SHAPE_WIDTH; - } - - /** - * The graphical representation of the legend shape. - * - * @param canvas the canvas to paint to - * @param renderer the series renderer - * @param x the x value of the point the shape should be drawn at - * @param y the y value of the point the shape should be drawn at - * @param seriesIndex the series index - * @param paint the paint to be used for drawing - */ - public void drawLegendShape(Canvas canvas, SimpleSeriesRenderer renderer, float x, float y, - int seriesIndex, Paint paint) { - canvas.drawLine(x, y, x + SHAPE_WIDTH, y, paint); - if (isRenderPoints(renderer)) { - pointsChart.drawLegendShape(canvas, renderer, x + 5, y, seriesIndex, paint); - } - } - - /** - * Returns if the chart should display the points as a certain shape. - * - * @param renderer the series renderer - */ - public boolean isRenderPoints(SimpleSeriesRenderer renderer) { - return ((XYSeriesRenderer) renderer).getPointStyle() != PointStyle.POINT; - } - - /** - * Returns the scatter chart to be used for drawing the data points. - * - * @return the data points scatter chart - */ - public ScatterChart getPointsChart() { - return pointsChart; - } - - /** - * Returns the chart type identifier. - * - * @return the chart type - */ - public String getChartType() { - return TYPE; - } - -} diff --git a/android-libraries/achartengine/src/org/achartengine/chart/PieChart.java b/android-libraries/achartengine/src/org/achartengine/chart/PieChart.java deleted file mode 100644 index d656a95eb..000000000 --- a/android-libraries/achartengine/src/org/achartengine/chart/PieChart.java +++ /dev/null @@ -1,136 +0,0 @@ -/** - * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.achartengine.chart; - -import java.util.ArrayList; -import java.util.List; - -import org.achartengine.model.CategorySeries; -import org.achartengine.model.Point; -import org.achartengine.model.SeriesSelection; -import org.achartengine.renderer.DefaultRenderer; - -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.Paint.Style; -import android.graphics.RectF; - -/** - * The pie chart rendering class. - */ -public class PieChart extends RoundChart { - /** Handles returning values when tapping on PieChart. */ - private PieMapper mPieMapper; - - /** - * Builds a new pie chart instance. - * - * @param dataset the series dataset - * @param renderer the series renderer - */ - public PieChart(CategorySeries dataset, DefaultRenderer renderer) { - super(dataset, renderer); - mPieMapper = new PieMapper(); - } - - /** - * The graphical representation of the pie chart. - * - * @param canvas the canvas to paint to - * @param x the top left x value of the view to draw to - * @param y the top left y value of the view to draw to - * @param width the width of the view to draw to - * @param height the height of the view to draw to - * @param paint the paint - */ - @Override - public void draw(Canvas canvas, int x, int y, int width, int height, Paint paint) { - paint.setAntiAlias(mRenderer.isAntialiasing()); - paint.setStyle(Style.FILL); - paint.setTextSize(mRenderer.getLabelsTextSize()); - int legendSize = getLegendSize(mRenderer, height / 5, 0); - int left = x; - int top = y; - int right = x + width; - int sLength = mDataset.getItemCount(); - double total = 0; - String[] titles = new String[sLength]; - for (int i = 0; i < sLength; i++) { - total += mDataset.getValue(i); - titles[i] = mDataset.getCategory(i); - } - if (mRenderer.isFitLegend()) { - legendSize = drawLegend(canvas, mRenderer, titles, left, right, y, width, height, legendSize, - paint, true); - } - int bottom = y + height - legendSize; - drawBackground(mRenderer, canvas, x, y, width, height, paint, false, DefaultRenderer.NO_COLOR); - - float currentAngle = mRenderer.getStartAngle(); - int mRadius = Math.min(Math.abs(right - left), Math.abs(bottom - top)); - int radius = (int) (mRadius * 0.35 * mRenderer.getScale()); - - if (mCenterX == NO_VALUE) { - mCenterX = (left + right) / 2; - } - if (mCenterY == NO_VALUE) { - mCenterY = (bottom + top) / 2; - } - - // Hook in clip detection after center has been calculated - mPieMapper.setDimensions(radius, mCenterX, mCenterY); - boolean loadPieCfg = !mPieMapper.areAllSegmentPresent(sLength); - if (loadPieCfg) { - mPieMapper.clearPieSegments(); - } - - float shortRadius = radius * 0.9f; - float longRadius = radius * 1.1f; - - RectF oval = new RectF(mCenterX - radius, mCenterY - radius, mCenterX + radius, mCenterY - + radius); - List prevLabelsBounds = new ArrayList(); - - for (int i = 0; i < sLength; i++) { - paint.setColor(mRenderer.getSeriesRendererAt(i).getColor()); - float value = (float) mDataset.getValue(i); - float angle = (float) (value / total * 360); - canvas.drawArc(oval, currentAngle, angle, true, paint); - drawLabel(canvas, mDataset.getCategory(i), mRenderer, prevLabelsBounds, mCenterX, mCenterY, - shortRadius, longRadius, currentAngle, angle, left, right, mRenderer.getLabelsColor(), - paint, true); - if (mRenderer.isDisplayValues()) { - drawLabel(canvas, getLabel(mDataset.getValue(i)), mRenderer, prevLabelsBounds, mCenterX, - mCenterY, shortRadius / 2, longRadius / 2, currentAngle, angle, left, right, - mRenderer.getLabelsColor(), paint, false); - } - - // Save details for getSeries functionality - if (loadPieCfg) { - mPieMapper.addPieSegment(i, value, currentAngle, angle); - } - currentAngle += angle; - } - prevLabelsBounds.clear(); - drawLegend(canvas, mRenderer, titles, left, right, y, width, height, legendSize, paint, false); - drawTitle(canvas, x, y, width, paint); - } - - public SeriesSelection getSeriesAndPointForScreenCoordinate(Point screenPoint) { - return mPieMapper.getSeriesAndPointForScreenCoordinate(screenPoint); - } - -} diff --git a/android-libraries/achartengine/src/org/achartengine/chart/PieMapper.java b/android-libraries/achartengine/src/org/achartengine/chart/PieMapper.java deleted file mode 100644 index 6e4b71504..000000000 --- a/android-libraries/achartengine/src/org/achartengine/chart/PieMapper.java +++ /dev/null @@ -1,139 +0,0 @@ -/** - * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.achartengine.chart; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - -import org.achartengine.model.Point; -import org.achartengine.model.SeriesSelection; - -/** - * PieChart Segment Selection Management. - */ -public class PieMapper implements Serializable { - - private List mPieSegmentList = new ArrayList(); - - private int mPieChartRadius; - - private int mCenterX, mCenterY; - - /** - * Set PieChart location on screen. - * - * @param pieRadius - * @param centerX - * @param centerY - */ - public void setDimensions(int pieRadius, int centerX, int centerY) { - mPieChartRadius = pieRadius; - mCenterX = centerX; - mCenterY = centerY; - } - - /** - * If we have all PieChart Config then there is no point in reloading it - * - * @param datasetSize - * @return true if cfg for each segment is present - */ - public boolean areAllSegmentPresent(int datasetSize) { - return mPieSegmentList.size() == datasetSize; - } - - /** - * Add configuration for a PieChart Segment - * - * @param dataIndex - * @param value - * @param startAngle - * @param angle - */ - public void addPieSegment(int dataIndex, float value, float startAngle, float angle) { - mPieSegmentList.add(new PieSegment(dataIndex, value, startAngle, angle)); - } - - /** - * Clears the pie segments list. - */ - public void clearPieSegments() { - mPieSegmentList.clear(); - } - - /** - * Fetches angle relative to pie chart center point where 3 O'Clock is 0 and - * 12 O'Clock is 270degrees - * - * @param screenPoint - * @return angle in degress from 0-360. - */ - public double getAngle(Point screenPoint) { - double dx = screenPoint.getX() - mCenterX; - // Minus to correct for coord re-mapping - double dy = -(screenPoint.getY() - mCenterY); - - double inRads = Math.atan2(dy, dx); - - // We need to map to coord system when 0 degree is at 3 O'clock, 270 at 12 - // O'clock - if (inRads < 0) - inRads = Math.abs(inRads); - else - inRads = 2 * Math.PI - inRads; - - return Math.toDegrees(inRads); - } - - /** - * Checks if Point falls within PieChart - * - * @param screenPoint - * @return true if in PieChart - */ - public boolean isOnPieChart(Point screenPoint) { - // Using a bit of Pythagoras - // inside circle if (x-center_x)**2 + (y-center_y)**2 <= radius**2: - - double sqValue = (Math.pow(mCenterX - screenPoint.getX(), 2) + Math.pow( - mCenterY - screenPoint.getY(), 2)); - - double radiusSquared = mPieChartRadius * mPieChartRadius; - boolean isOnPieChart = sqValue <= radiusSquared; - return isOnPieChart; - } - - /** - * Fetches the SeriesSelection for the PieSegment selected. - * - * @param screenPoint - the user tap location - * @return null if screen point is not in PieChart or its config if it is - */ - public SeriesSelection getSeriesAndPointForScreenCoordinate(Point screenPoint) { - if (isOnPieChart(screenPoint)) { - double angleFromPieCenter = getAngle(screenPoint); - - for (PieSegment pieSeg : mPieSegmentList) { - if (pieSeg.isInSegment(angleFromPieCenter)) { - return new SeriesSelection(0, pieSeg.getDataIndex(), pieSeg.getValue(), - pieSeg.getValue()); - } - } - } - return null; - } -} diff --git a/android-libraries/achartengine/src/org/achartengine/chart/PieSegment.java b/android-libraries/achartengine/src/org/achartengine/chart/PieSegment.java deleted file mode 100644 index 0fb0a2e48..000000000 --- a/android-libraries/achartengine/src/org/achartengine/chart/PieSegment.java +++ /dev/null @@ -1,70 +0,0 @@ -/** - * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.achartengine.chart; - -import java.io.Serializable; - -/** - * Holds An PieChart Segment - */ -public class PieSegment implements Serializable { - private float mStartAngle; - - private float mEndAngle; - - private int mDataIndex; - - private float mValue; - - public PieSegment(int dataIndex, float value, float startAngle, float angle) { - mStartAngle = startAngle; - mEndAngle = angle + startAngle; - mDataIndex = dataIndex; - mValue = value; - } - - /** - * Checks if angle falls in segment. - * - * @param angle - * @return true if in segment, false otherwise. - */ - public boolean isInSegment(double angle) { - return angle >= mStartAngle && angle <= mEndAngle; - } - - protected float getStartAngle() { - return mStartAngle; - } - - protected float getEndAngle() { - return mEndAngle; - } - - protected int getDataIndex() { - return mDataIndex; - } - - protected float getValue() { - return mValue; - } - - public String toString() { - return "mDataIndex=" + mDataIndex + ",mValue=" + mValue + ",mStartAngle=" + mStartAngle - + ",mEndAngle=" + mEndAngle; - } - -} diff --git a/android-libraries/achartengine/src/org/achartengine/chart/PointStyle.java b/android-libraries/achartengine/src/org/achartengine/chart/PointStyle.java deleted file mode 100644 index 29a2311a9..000000000 --- a/android-libraries/achartengine/src/org/achartengine/chart/PointStyle.java +++ /dev/null @@ -1,90 +0,0 @@ -/** - * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.achartengine.chart; - -/** - * The chart point style enumerator. - */ -public enum PointStyle { - X("x"), CIRCLE("circle"), TRIANGLE("triangle"), SQUARE("square"), DIAMOND("diamond"), POINT( - "point"); - - /** The point shape name. */ - private String mName; - - /** - * The point style enum constructor. - * - * @param name the name - */ - private PointStyle(String name) { - mName = name; - } - - /** - * Returns the point shape name. - * - * @return the point shape name - */ - public String getName() { - return mName; - } - - /** - * Returns the point shape name. - * - * @return the point shape name - */ - public String toString() { - return getName(); - } - - /** - * Return the point shape that has the provided symbol. - * - * @param name the point style name - * @return the point shape - */ - public static PointStyle getPointStyleForName(String name) { - PointStyle pointStyle = null; - PointStyle[] styles = values(); - int length = styles.length; - for (int i = 0; i < length && pointStyle == null; i++) { - if (styles[i].mName.equals(name)) { - pointStyle = styles[i]; - } - } - return pointStyle; - } - - /** - * Returns the point shape index based on the given name. - * - * @return the point shape index - */ - public static int getIndexForName(String name) { - int index = -1; - PointStyle[] styles = values(); - int length = styles.length; - for (int i = 0; i < length && index < 0; i++) { - if (styles[i].mName.equals(name)) { - index = i; - } - } - return Math.max(0, index); - } - -} diff --git a/android-libraries/achartengine/src/org/achartengine/chart/RangeBarChart.java b/android-libraries/achartengine/src/org/achartengine/chart/RangeBarChart.java deleted file mode 100644 index 105f509a4..000000000 --- a/android-libraries/achartengine/src/org/achartengine/chart/RangeBarChart.java +++ /dev/null @@ -1,145 +0,0 @@ -/** - * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.achartengine.chart; - -import org.achartengine.model.XYMultipleSeriesDataset; -import org.achartengine.model.XYSeries; -import org.achartengine.renderer.SimpleSeriesRenderer; -import org.achartengine.renderer.XYMultipleSeriesRenderer; - -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.Paint.Style; - -/** - * The range bar chart rendering class. - */ -public class RangeBarChart extends BarChart { - /** The chart type. */ - public static final String TYPE = "RangeBar"; - - RangeBarChart() { - } - - RangeBarChart(Type type) { - super(type); - } - - /** - * Builds a new range bar chart instance. - * - * @param dataset the multiple series dataset - * @param renderer the multiple series renderer - * @param type the range bar chart type - */ - public RangeBarChart(XYMultipleSeriesDataset dataset, XYMultipleSeriesRenderer renderer, Type type) { - super(dataset, renderer, type); - } - - /** - * The graphical representation of a series. - * - * @param canvas the canvas to paint to - * @param paint the paint to be used for drawing - * @param points the array of points to be used for drawing the series - * @param seriesRenderer the series renderer - * @param yAxisValue the minimum value of the y axis - * @param seriesIndex the index of the series currently being drawn - * @param startIndex the start index of the rendering points - */ - public void drawSeries(Canvas canvas, Paint paint, float[] points, - SimpleSeriesRenderer seriesRenderer, float yAxisValue, int seriesIndex, int startIndex) { - int seriesNr = mDataset.getSeriesCount(); - int length = points.length; - paint.setColor(seriesRenderer.getColor()); - paint.setStyle(Style.FILL); - float halfDiffX = getHalfDiffX(points, length, seriesNr); - int start = 0; - if (startIndex > 0) { - start = 2; - } - for (int i = start; i < length; i += 4) { - if (points.length > i + 3) { - float xMin = points[i]; - float yMin = points[i + 1]; - // xMin = xMax - float xMax = points[i + 2]; - float yMax = points[i + 3]; - drawBar(canvas, xMin, yMin, xMax, yMax, halfDiffX, seriesNr, seriesIndex, paint); - } - } - paint.setColor(seriesRenderer.getColor()); - } - - /** - * The graphical representation of the series values as text. - * - * @param canvas the canvas to paint to - * @param series the series to be painted - * @param renderer the series renderer - * @param paint the paint to be used for drawing - * @param points the array of points to be used for drawing the series - * @param seriesIndex the index of the series currently being drawn - * @param startIndex the start index of the rendering points - */ - protected void drawChartValuesText(Canvas canvas, XYSeries series, SimpleSeriesRenderer renderer, - Paint paint, float[] points, int seriesIndex, int startIndex) { - int seriesNr = mDataset.getSeriesCount(); - float halfDiffX = getHalfDiffX(points, points.length, seriesNr); - int start = 0; - if (startIndex > 0) { - start = 2; - } - for (int i = start; i < points.length; i += 4) { - int index = startIndex + i / 2; - float x = points[i]; - if (mType == Type.DEFAULT) { - x += seriesIndex * 2 * halfDiffX - (seriesNr - 1.5f) * halfDiffX; - } - - if (!isNullValue(series.getY(index + 1)) && points.length > i + 3) { - // draw the maximum value - drawText(canvas, getLabel(series.getY(index + 1)), x, - points[i + 3] - renderer.getChartValuesSpacing(), paint, 0); - } - if (!isNullValue(series.getY(index)) && points.length > i + 1) { - // draw the minimum value - drawText(canvas, getLabel(series.getY(index)), x, - points[i + 1] + renderer.getChartValuesTextSize() + renderer.getChartValuesSpacing() - - 3, paint, 0); - } - } - } - - /** - * Returns the value of a constant used to calculate the half-distance. - * - * @return the constant value - */ - protected float getCoeficient() { - return 0.5f; - } - - /** - * Returns the chart type identifier. - * - * @return the chart type - */ - public String getChartType() { - return TYPE; - } - -} diff --git a/android-libraries/achartengine/src/org/achartengine/chart/RangeStackedBarChart.java b/android-libraries/achartengine/src/org/achartengine/chart/RangeStackedBarChart.java deleted file mode 100644 index 4da4f0068..000000000 --- a/android-libraries/achartengine/src/org/achartengine/chart/RangeStackedBarChart.java +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.achartengine.chart; - -public class RangeStackedBarChart extends RangeBarChart { - /** The chart type. */ - public static final String TYPE = "RangeStackedBar"; - - RangeStackedBarChart() { - super(Type.STACKED); - } - - public String getChartType() { - return TYPE; - } -} \ No newline at end of file diff --git a/android-libraries/achartengine/src/org/achartengine/chart/RoundChart.java b/android-libraries/achartengine/src/org/achartengine/chart/RoundChart.java deleted file mode 100644 index 1a2121d44..000000000 --- a/android-libraries/achartengine/src/org/achartengine/chart/RoundChart.java +++ /dev/null @@ -1,143 +0,0 @@ -/** - * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.achartengine.chart; - -import org.achartengine.model.CategorySeries; -import org.achartengine.renderer.DefaultRenderer; -import org.achartengine.renderer.SimpleSeriesRenderer; - -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.Paint.Align; - -/** - * An abstract class to be extended by round like chart rendering classes. - */ -public abstract class RoundChart extends AbstractChart { - /** The legend shape width. */ - protected static final int SHAPE_WIDTH = 10; - /** The series dataset. */ - protected CategorySeries mDataset; - /** The series renderer. */ - protected DefaultRenderer mRenderer; - /** A no value constant. */ - protected static final int NO_VALUE = Integer.MAX_VALUE; - /** The chart center X axis. */ - protected int mCenterX = NO_VALUE; - /** The chart center y axis. */ - protected int mCenterY = NO_VALUE; - - /** - * Round chart. - * - * @param dataset the series dataset - * @param renderer the series renderer - */ - public RoundChart(CategorySeries dataset, DefaultRenderer renderer) { - mDataset = dataset; - mRenderer = renderer; - } - - /** - * The graphical representation of the round chart title. - * - * @param canvas the canvas to paint to - * @param x the top left x value of the view to draw to - * @param y the top left y value of the view to draw to - * @param width the width of the view to draw to - * @param paint the paint - */ - public void drawTitle(Canvas canvas, int x, int y, int width, Paint paint) { - if (mRenderer.isShowLabels()) { - paint.setColor(mRenderer.getLabelsColor()); - paint.setTextAlign(Align.CENTER); - paint.setTextSize(mRenderer.getChartTitleTextSize()); - drawString(canvas, mRenderer.getChartTitle(), x + width / 2, - y + mRenderer.getChartTitleTextSize(), paint); - } - } - - /** - * Returns the legend shape width. - * - * @param seriesIndex the series index - * @return the legend shape width - */ - public int getLegendShapeWidth(int seriesIndex) { - return SHAPE_WIDTH; - } - - /** - * The graphical representation of the legend shape. - * - * @param canvas the canvas to paint to - * @param renderer the series renderer - * @param x the x value of the point the shape should be drawn at - * @param y the y value of the point the shape should be drawn at - * @param seriesIndex the series index - * @param paint the paint to be used for drawing - */ - public void drawLegendShape(Canvas canvas, SimpleSeriesRenderer renderer, float x, float y, - int seriesIndex, Paint paint) { - canvas.drawRect(x, y - SHAPE_WIDTH / 2, x + SHAPE_WIDTH, y + SHAPE_WIDTH / 2, paint); - } - - /** - * Returns the renderer. - * - * @return the renderer - */ - public DefaultRenderer getRenderer() { - return mRenderer; - } - - /** - * Returns the center on X axis. - * - * @return the center on X axis - */ - public int getCenterX() { - return mCenterX; - } - - /** - * Returns the center on Y axis. - * - * @return the center on Y axis - */ - public int getCenterY() { - return mCenterY; - } - - /** - * Sets a new center on X axis. - * - * @param centerX center on X axis - */ - public void setCenterX(int centerX) { - mCenterX = centerX; - } - - /** - * Sets a new center on Y axis. - * - * @param centerY center on Y axis - */ - public void setCenterY(int centerY) { - mCenterY = centerY; - } - -} diff --git a/android-libraries/achartengine/src/org/achartengine/chart/ScatterChart.java b/android-libraries/achartengine/src/org/achartengine/chart/ScatterChart.java deleted file mode 100644 index 1d3b2a184..000000000 --- a/android-libraries/achartengine/src/org/achartengine/chart/ScatterChart.java +++ /dev/null @@ -1,266 +0,0 @@ -/** - * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.achartengine.chart; - -import org.achartengine.model.XYMultipleSeriesDataset; -import org.achartengine.renderer.SimpleSeriesRenderer; -import org.achartengine.renderer.XYMultipleSeriesRenderer; -import org.achartengine.renderer.XYSeriesRenderer; - -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.Paint.Style; -import android.graphics.RectF; - -/** - * The scatter chart rendering class. - */ -public class ScatterChart extends XYChart { - /** The constant to identify this chart type. */ - public static final String TYPE = "Scatter"; - /** The default point shape size. */ - private static final float SIZE = 3; - /** The legend shape width. */ - private static final int SHAPE_WIDTH = 10; - /** The point shape size. */ - private float size = SIZE; - - ScatterChart() { - } - - /** - * Builds a new scatter chart instance. - * - * @param dataset the multiple series dataset - * @param renderer the multiple series renderer - */ - public ScatterChart(XYMultipleSeriesDataset dataset, XYMultipleSeriesRenderer renderer) { - super(dataset, renderer); - size = renderer.getPointSize(); - } - - // TODO: javadoc - protected void setDatasetRenderer(XYMultipleSeriesDataset dataset, - XYMultipleSeriesRenderer renderer) { - super.setDatasetRenderer(dataset, renderer); - size = renderer.getPointSize(); - } - - /** - * The graphical representation of a series. - * - * @param canvas the canvas to paint to - * @param paint the paint to be used for drawing - * @param points the array of points to be used for drawing the series - * @param seriesRenderer the series renderer - * @param yAxisValue the minimum value of the y axis - * @param seriesIndex the index of the series currently being drawn - * @param startIndex the start index of the rendering points - */ - public void drawSeries(Canvas canvas, Paint paint, float[] points, - SimpleSeriesRenderer seriesRenderer, float yAxisValue, int seriesIndex, int startIndex) { - XYSeriesRenderer renderer = (XYSeriesRenderer) seriesRenderer; - paint.setColor(renderer.getColor()); - if (renderer.isFillPoints()) { - paint.setStyle(Style.FILL); - } else { - paint.setStyle(Style.STROKE); - } - int length = points.length; - switch (renderer.getPointStyle()) { - case X: - for (int i = 0; i < length; i += 2) { - drawX(canvas, paint, points[i], points[i + 1]); - } - break; - case CIRCLE: - for (int i = 0; i < length; i += 2) { - drawCircle(canvas, paint, points[i], points[i + 1]); - } - break; - case TRIANGLE: - float[] path = new float[6]; - for (int i = 0; i < length; i += 2) { - drawTriangle(canvas, paint, path, points[i], points[i + 1]); - } - break; - case SQUARE: - for (int i = 0; i < length; i += 2) { - drawSquare(canvas, paint, points[i], points[i + 1]); - } - break; - case DIAMOND: - path = new float[8]; - for (int i = 0; i < length; i += 2) { - drawDiamond(canvas, paint, path, points[i], points[i + 1]); - } - break; - case POINT: - canvas.drawPoints(points, paint); - break; - } - } - - @Override - protected ClickableArea[] clickableAreasForPoints(float[] points, double[] values, - float yAxisValue, int seriesIndex, int startIndex) { - int length = points.length; - ClickableArea[] ret = new ClickableArea[length / 2]; - for (int i = 0; i < length; i += 2) { - int selectableBuffer = mRenderer.getSelectableBuffer(); - ret[i / 2] = new ClickableArea(new RectF(points[i] - selectableBuffer, points[i + 1] - - selectableBuffer, points[i] + selectableBuffer, points[i + 1] + selectableBuffer), - values[i], values[i + 1]); - } - return ret; - } - - /** - * Returns the legend shape width. - * - * @param seriesIndex the series index - * @return the legend shape width - */ - public int getLegendShapeWidth(int seriesIndex) { - return SHAPE_WIDTH; - } - - /** - * The graphical representation of the legend shape. - * - * @param canvas the canvas to paint to - * @param renderer the series renderer - * @param x the x value of the point the shape should be drawn at - * @param y the y value of the point the shape should be drawn at - * @param seriesIndex the series index - * @param paint the paint to be used for drawing - */ - public void drawLegendShape(Canvas canvas, SimpleSeriesRenderer renderer, float x, float y, - int seriesIndex, Paint paint) { - if (((XYSeriesRenderer) renderer).isFillPoints()) { - paint.setStyle(Style.FILL); - } else { - paint.setStyle(Style.STROKE); - } - switch (((XYSeriesRenderer) renderer).getPointStyle()) { - case X: - drawX(canvas, paint, x + SHAPE_WIDTH, y); - break; - case CIRCLE: - drawCircle(canvas, paint, x + SHAPE_WIDTH, y); - break; - case TRIANGLE: - drawTriangle(canvas, paint, new float[6], x + SHAPE_WIDTH, y); - break; - case SQUARE: - drawSquare(canvas, paint, x + SHAPE_WIDTH, y); - break; - case DIAMOND: - drawDiamond(canvas, paint, new float[8], x + SHAPE_WIDTH, y); - break; - case POINT: - canvas.drawPoint(x + SHAPE_WIDTH, y, paint); - break; - } - } - - /** - * The graphical representation of an X point shape. - * - * @param canvas the canvas to paint to - * @param paint the paint to be used for drawing - * @param x the x value of the point the shape should be drawn at - * @param y the y value of the point the shape should be drawn at - */ - private void drawX(Canvas canvas, Paint paint, float x, float y) { - canvas.drawLine(x - size, y - size, x + size, y + size, paint); - canvas.drawLine(x + size, y - size, x - size, y + size, paint); - } - - /** - * The graphical representation of a circle point shape. - * - * @param canvas the canvas to paint to - * @param paint the paint to be used for drawing - * @param x the x value of the point the shape should be drawn at - * @param y the y value of the point the shape should be drawn at - */ - private void drawCircle(Canvas canvas, Paint paint, float x, float y) { - canvas.drawCircle(x, y, size, paint); - } - - /** - * The graphical representation of a triangle point shape. - * - * @param canvas the canvas to paint to - * @param paint the paint to be used for drawing - * @param path the triangle path - * @param x the x value of the point the shape should be drawn at - * @param y the y value of the point the shape should be drawn at - */ - private void drawTriangle(Canvas canvas, Paint paint, float[] path, float x, float y) { - path[0] = x; - path[1] = y - size - size / 2; - path[2] = x - size; - path[3] = y + size; - path[4] = x + size; - path[5] = path[3]; - drawPath(canvas, path, paint, true); - } - - /** - * The graphical representation of a square point shape. - * - * @param canvas the canvas to paint to - * @param paint the paint to be used for drawing - * @param x the x value of the point the shape should be drawn at - * @param y the y value of the point the shape should be drawn at - */ - private void drawSquare(Canvas canvas, Paint paint, float x, float y) { - canvas.drawRect(x - size, y - size, x + size, y + size, paint); - } - - /** - * The graphical representation of a diamond point shape. - * - * @param canvas the canvas to paint to - * @param paint the paint to be used for drawing - * @param path the diamond path - * @param x the x value of the point the shape should be drawn at - * @param y the y value of the point the shape should be drawn at - */ - private void drawDiamond(Canvas canvas, Paint paint, float[] path, float x, float y) { - path[0] = x; - path[1] = y - size; - path[2] = x - size; - path[3] = y; - path[4] = x; - path[5] = y + size; - path[6] = x + size; - path[7] = y; - drawPath(canvas, path, paint, true); - } - - /** - * Returns the chart type identifier. - * - * @return the chart type - */ - public String getChartType() { - return TYPE; - } - -} \ No newline at end of file diff --git a/android-libraries/achartengine/src/org/achartengine/chart/TimeChart.java b/android-libraries/achartengine/src/org/achartengine/chart/TimeChart.java deleted file mode 100644 index ba201de78..000000000 --- a/android-libraries/achartengine/src/org/achartengine/chart/TimeChart.java +++ /dev/null @@ -1,226 +0,0 @@ -/** - * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.achartengine.chart; - -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; - -import org.achartengine.model.XYMultipleSeriesDataset; -import org.achartengine.model.XYSeries; -import org.achartengine.renderer.XYMultipleSeriesRenderer; - -import android.graphics.Canvas; -import android.graphics.Paint; - -/** - * The time chart rendering class. - */ -public class TimeChart extends LineChart { - /** The constant to identify this chart type. */ - public static final String TYPE = "Time"; - /** The number of milliseconds in a day. */ - public static final long DAY = 24 * 60 * 60 * 1000; - /** The date format pattern to be used in formatting the X axis labels. */ - private String mDateFormat; - /** The starting point for labels. */ - private Double mStartPoint; - - TimeChart() { - } - - /** - * Builds a new time chart instance. - * - * @param dataset the multiple series dataset - * @param renderer the multiple series renderer - */ - public TimeChart(XYMultipleSeriesDataset dataset, XYMultipleSeriesRenderer renderer) { - super(dataset, renderer); - } - - /** - * Returns the date format pattern to be used for formatting the X axis - * labels. - * - * @return the date format pattern for the X axis labels - */ - public String getDateFormat() { - return mDateFormat; - } - - /** - * Sets the date format pattern to be used for formatting the X axis labels. - * - * @param format the date format pattern for the X axis labels. If null, an - * appropriate default format will be used. - */ - public void setDateFormat(String format) { - mDateFormat = format; - } - - /** - * The graphical representation of the labels on the X axis. - * - * @param xLabels the X labels values - * @param xTextLabelLocations the X text label locations - * @param canvas the canvas to paint to - * @param paint the paint to be used for drawing - * @param left the left value of the labels area - * @param top the top value of the labels area - * @param bottom the bottom value of the labels area - * @param xPixelsPerUnit the amount of pixels per one unit in the chart labels - * @param minX the minimum value on the X axis in the chart - * @param maxX the maximum value on the X axis in the chart - */ - @Override - protected void drawXLabels(List xLabels, Double[] xTextLabelLocations, Canvas canvas, - Paint paint, int left, int top, int bottom, double xPixelsPerUnit, double minX, double maxX) { - int length = xLabels.size(); - if (length > 0) { - boolean showLabels = mRenderer.isShowLabels(); - boolean showGridY = mRenderer.isShowGridY(); - DateFormat format = getDateFormat(xLabels.get(0), xLabels.get(length - 1)); - for (int i = 0; i < length; i++) { - long label = Math.round(xLabels.get(i)); - float xLabel = (float) (left + xPixelsPerUnit * (label - minX)); - if (showLabels) { - paint.setColor(mRenderer.getXLabelsColor()); - canvas - .drawLine(xLabel, bottom, xLabel, bottom + mRenderer.getLabelsTextSize() / 3, paint); - drawText(canvas, format.format(new Date(label)), xLabel, - bottom + mRenderer.getLabelsTextSize() * 4 / 3, paint, mRenderer.getXLabelsAngle()); - } - if (showGridY) { - paint.setColor(mRenderer.getGridColor()); - canvas.drawLine(xLabel, bottom, xLabel, top, paint); - } - } - } - drawXTextLabels(xTextLabelLocations, canvas, paint, true, left, top, bottom, xPixelsPerUnit, - minX, maxX); - } - - /** - * Returns the date format pattern to be used, based on the date range. - * - * @param start the start date in milliseconds - * @param end the end date in milliseconds - * @return the date format - */ - private DateFormat getDateFormat(double start, double end) { - if (mDateFormat != null) { - SimpleDateFormat format = null; - try { - format = new SimpleDateFormat(mDateFormat); - return format; - } catch (Exception e) { - // do nothing here - } - } - DateFormat format = SimpleDateFormat.getDateInstance(SimpleDateFormat.MEDIUM); - double diff = end - start; - if (diff > DAY && diff < 5 * DAY) { - format = SimpleDateFormat.getDateTimeInstance(SimpleDateFormat.SHORT, SimpleDateFormat.SHORT); - } else if (diff < DAY) { - format = SimpleDateFormat.getTimeInstance(SimpleDateFormat.MEDIUM); - } - return format; - } - - /** - * Returns the chart type identifier. - * - * @return the chart type - */ - public String getChartType() { - return TYPE; - } - - protected List getXLabels(double min, double max, int count) { - final List result = new ArrayList(); - if (!mRenderer.isXRoundedLabels()) { - if (mDataset.getSeriesCount() > 0) { - XYSeries series = mDataset.getSeriesAt(0); - int length = series.getItemCount(); - int intervalLength = 0; - int startIndex = -1; - for (int i = 0; i < length; i++) { - double value = series.getX(i); - if (min <= value && value <= max) { - intervalLength++; - if (startIndex < 0) { - startIndex = i; - } - } - } - if (intervalLength < count) { - for (int i = startIndex; i < startIndex + intervalLength; i++) { - result.add(series.getX(i)); - } - } else { - float step = (float) intervalLength / count; - int intervalCount = 0; - for (int i = 0; i < length && intervalCount < count; i++) { - double value = series.getX(Math.round(i * step)); - if (min <= value && value <= max) { - result.add(value); - intervalCount++; - } - } - } - return result; - } else { - return super.getXLabels(min, max, count); - } - } - if (mStartPoint == null) { - mStartPoint = min - (min % DAY) + DAY + new Date(Math.round(min)).getTimezoneOffset() * 60 - * 1000; - } - if (count > 25) { - count = 25; - } - - - final double cycleMath = (max - min) / count; - if (cycleMath <= 0) { - return result; - } - double cycle = DAY; - - if (cycleMath <= DAY) { - while (cycleMath < cycle / 2) { - cycle = cycle / 2; - } - } else { - while (cycleMath > cycle) { - cycle = cycle * 2; - } - } - - double val = mStartPoint - Math.floor((mStartPoint - min) / cycle) * cycle; - int i = 0; - while (val < max && i++ <= count) { - result.add(val); - val += cycle; - } - - return result; - } -} diff --git a/android-libraries/achartengine/src/org/achartengine/chart/XYChart.java b/android-libraries/achartengine/src/org/achartengine/chart/XYChart.java deleted file mode 100644 index 6b531d60b..000000000 --- a/android-libraries/achartengine/src/org/achartengine/chart/XYChart.java +++ /dev/null @@ -1,905 +0,0 @@ -/** - * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.achartengine.chart; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.SortedMap; - -import org.achartengine.model.Point; -import org.achartengine.model.SeriesSelection; -import org.achartengine.model.XYMultipleSeriesDataset; -import org.achartengine.model.XYSeries; -import org.achartengine.renderer.BasicStroke; -import org.achartengine.renderer.DefaultRenderer; -import org.achartengine.renderer.SimpleSeriesRenderer; -import org.achartengine.renderer.XYMultipleSeriesRenderer; -import org.achartengine.renderer.XYMultipleSeriesRenderer.Orientation; -import org.achartengine.util.MathHelper; - -import android.graphics.Canvas; -import android.graphics.DashPathEffect; -import android.graphics.Paint; -import android.graphics.Paint.Align; -import android.graphics.Paint.Cap; -import android.graphics.Paint.Join; -import android.graphics.Paint.Style; -import android.graphics.PathEffect; -import android.graphics.Rect; -import android.graphics.RectF; -import android.graphics.Typeface; - -/** - * The XY chart rendering class. - */ -public abstract class XYChart extends AbstractChart { - /** The multiple series dataset. */ - protected XYMultipleSeriesDataset mDataset; - /** The multiple series renderer. */ - protected XYMultipleSeriesRenderer mRenderer; - /** The current scale value. */ - private float mScale; - /** The current translate value. */ - private float mTranslate; - /** The canvas center point. */ - private Point mCenter; - /** The visible chart area, in screen coordinates. */ - private Rect mScreenR; - /** The calculated range. */ - private final Map mCalcRange = new HashMap(); - - /** - * The clickable areas for all points. The array index is the series index, - * and the RectF list index is the point index in that series. - */ - private Map> clickableAreas = new HashMap>(); - - protected XYChart() { - } - - /** - * Builds a new XY chart instance. - * - * @param dataset the multiple series dataset - * @param renderer the multiple series renderer - */ - public XYChart(XYMultipleSeriesDataset dataset, XYMultipleSeriesRenderer renderer) { - mDataset = dataset; - mRenderer = renderer; - } - - // TODO: javadoc - protected void setDatasetRenderer(XYMultipleSeriesDataset dataset, - XYMultipleSeriesRenderer renderer) { - mDataset = dataset; - mRenderer = renderer; - } - - /** - * The graphical representation of the XY chart. - * - * @param canvas the canvas to paint to - * @param x the top left x value of the view to draw to - * @param y the top left y value of the view to draw to - * @param width the width of the view to draw to - * @param height the height of the view to draw to - * @param paint the paint - */ - public void draw(Canvas canvas, int x, int y, int width, int height, Paint paint) { - paint.setAntiAlias(mRenderer.isAntialiasing()); - int legendSize = getLegendSize(mRenderer, height / 5, mRenderer.getAxisTitleTextSize()); - int[] margins = mRenderer.getMargins(); - int left = x + margins[1]; - int top = y + margins[0]; - int right = x + width - margins[3]; - int sLength = mDataset.getSeriesCount(); - String[] titles = new String[sLength]; - for (int i = 0; i < sLength; i++) { - titles[i] = mDataset.getSeriesAt(i).getTitle(); - } - if (mRenderer.isFitLegend() && mRenderer.isShowLegend()) { - legendSize = drawLegend(canvas, mRenderer, titles, left, right, y, width, height, legendSize, - paint, true); - } - int bottom = y + height - margins[2] - legendSize; - if (mScreenR == null) { - mScreenR = new Rect(); - } - mScreenR.set(left, top, right, bottom); - drawBackground(mRenderer, canvas, x, y, width, height, paint, false, DefaultRenderer.NO_COLOR); - - if (paint.getTypeface() == null - || !paint.getTypeface().toString().equals(mRenderer.getTextTypefaceName()) - || paint.getTypeface().getStyle() != mRenderer.getTextTypefaceStyle()) { - paint.setTypeface(Typeface.create(mRenderer.getTextTypefaceName(), - mRenderer.getTextTypefaceStyle())); - } - Orientation or = mRenderer.getOrientation(); - if (or == Orientation.VERTICAL) { - right -= legendSize; - bottom += legendSize - 20; - } - int angle = or.getAngle(); - boolean rotate = angle == 90; - mScale = (float) (height) / width; - mTranslate = Math.abs(width - height) / 2; - if (mScale < 1) { - mTranslate *= -1; - } - mCenter = new Point((x + width) / 2, (y + height) / 2); - if (rotate) { - transform(canvas, angle, false); - } - - int maxScaleNumber = -Integer.MAX_VALUE; - for (int i = 0; i < sLength; i++) { - maxScaleNumber = Math.max(maxScaleNumber, mDataset.getSeriesAt(i).getScaleNumber()); - } - maxScaleNumber++; - if (maxScaleNumber < 0) { - return; - } - double[] minX = new double[maxScaleNumber]; - double[] maxX = new double[maxScaleNumber]; - double[] minY = new double[maxScaleNumber]; - double[] maxY = new double[maxScaleNumber]; - boolean[] isMinXSet = new boolean[maxScaleNumber]; - boolean[] isMaxXSet = new boolean[maxScaleNumber]; - boolean[] isMinYSet = new boolean[maxScaleNumber]; - boolean[] isMaxYSet = new boolean[maxScaleNumber]; - - for (int i = 0; i < maxScaleNumber; i++) { - minX[i] = mRenderer.getXAxisMin(i); - maxX[i] = mRenderer.getXAxisMax(i); - minY[i] = mRenderer.getYAxisMin(i); - maxY[i] = mRenderer.getYAxisMax(i); - isMinXSet[i] = mRenderer.isMinXSet(i); - isMaxXSet[i] = mRenderer.isMaxXSet(i); - isMinYSet[i] = mRenderer.isMinYSet(i); - isMaxYSet[i] = mRenderer.isMaxYSet(i); - if (mCalcRange.get(i) == null) { - mCalcRange.put(i, new double[4]); - } - } - double[] xPixelsPerUnit = new double[maxScaleNumber]; - double[] yPixelsPerUnit = new double[maxScaleNumber]; - for (int i = 0; i < sLength; i++) { - XYSeries series = mDataset.getSeriesAt(i); - int scale = series.getScaleNumber(); - if (series.getItemCount() == 0) { - continue; - } - if (!isMinXSet[scale]) { - double minimumX = series.getMinX(); - minX[scale] = Math.min(minX[scale], minimumX); - mCalcRange.get(scale)[0] = minX[scale]; - } - if (!isMaxXSet[scale]) { - double maximumX = series.getMaxX(); - maxX[scale] = Math.max(maxX[scale], maximumX); - mCalcRange.get(scale)[1] = maxX[scale]; - } - if (!isMinYSet[scale]) { - double minimumY = series.getMinY(); - minY[scale] = Math.min(minY[scale], (float) minimumY); - mCalcRange.get(scale)[2] = minY[scale]; - } - if (!isMaxYSet[scale]) { - double maximumY = series.getMaxY(); - maxY[scale] = Math.max(maxY[scale], (float) maximumY); - mCalcRange.get(scale)[3] = maxY[scale]; - } - } - for (int i = 0; i < maxScaleNumber; i++) { - if (maxX[i] - minX[i] != 0) { - xPixelsPerUnit[i] = (right - left) / (maxX[i] - minX[i]); - } - if (maxY[i] - minY[i] != 0) { - yPixelsPerUnit[i] = (float) ((bottom - top) / (maxY[i] - minY[i])); - } - } - - boolean hasValues = false; - // use a linked list for these reasons: - // 1) Avoid a large contiguous memory allocation - // 2) We don't need random seeking, only sequential reading/writing, so - // linked list makes sense - clickableAreas = new HashMap>(); - for (int i = 0; i < sLength; i++) { - XYSeries series = mDataset.getSeriesAt(i); - int scale = series.getScaleNumber(); - if (series.getItemCount() == 0) { - continue; - } - - hasValues = true; - SimpleSeriesRenderer seriesRenderer = mRenderer.getSeriesRendererAt(i); - - // int originalValuesLength = series.getItemCount(); - // int valuesLength = originalValuesLength; - // int length = valuesLength * 2; - - List points = new ArrayList(); - List values = new ArrayList(); - float yAxisValue = Math.min(bottom, (float) (bottom + yPixelsPerUnit[scale] * minY[scale])); - LinkedList clickableArea = new LinkedList(); - - clickableAreas.put(i, clickableArea); - - SortedMap range = series.getRange(minX[scale], maxX[scale], 1); - int startIndex = -1; - - for (Entry value : range.entrySet()) { - - double xValue = value.getKey(); - double yValue = value.getValue(); - if (startIndex < 0) { - startIndex = series.getIndexForKey(xValue); - } - - // points.add((float) (left + xPixelsPerUnit[scale] - // * (value.getKey().floatValue() - minX[scale]))); - // points.add((float) (bottom - yPixelsPerUnit[scale] - // * (value.getValue().floatValue() - minY[scale]))); - values.add(value.getKey()); - values.add(value.getValue()); - - if (!isNullValue(yValue)) { - points.add((float) (left + xPixelsPerUnit[scale] * (xValue - minX[scale]))); - points.add((float) (bottom - yPixelsPerUnit[scale] * (yValue - minY[scale]))); - } else if (isRenderNullValues()) { - points.add((float) (left + xPixelsPerUnit[scale] * (xValue - minX[scale]))); - points.add((float) (bottom - yPixelsPerUnit[scale] * (-minY[scale]))); - } else { - if (points.size() > 0) { - drawSeries(series, canvas, paint, points, seriesRenderer, yAxisValue, i, or, startIndex); - ClickableArea[] clickableAreasForSubSeries = clickableAreasForPoints( - MathHelper.getFloats(points), MathHelper.getDoubles(values), yAxisValue, i, - startIndex); - clickableArea.addAll(Arrays.asList(clickableAreasForSubSeries)); - points.clear(); - values.clear(); - } - clickableArea.add(null); - } - } - - if (points.size() > 0) { - drawSeries(series, canvas, paint, points, seriesRenderer, yAxisValue, i, or, startIndex); - ClickableArea[] clickableAreasForSubSeries = clickableAreasForPoints( - MathHelper.getFloats(points), MathHelper.getDoubles(values), yAxisValue, i, startIndex); - clickableArea.addAll(Arrays.asList(clickableAreasForSubSeries)); - } - } - - // draw stuff over the margins such as data doesn't render on these areas - drawBackground(mRenderer, canvas, x, bottom, width, height - bottom, paint, true, - mRenderer.getMarginsColor()); - drawBackground(mRenderer, canvas, x, y, width, margins[0], paint, true, - mRenderer.getMarginsColor()); - if (or == Orientation.HORIZONTAL) { - drawBackground(mRenderer, canvas, x, y, left - x, height - y, paint, true, - mRenderer.getMarginsColor()); - drawBackground(mRenderer, canvas, right, y, margins[3], height - y, paint, true, - mRenderer.getMarginsColor()); - } else if (or == Orientation.VERTICAL) { - drawBackground(mRenderer, canvas, right, y, width - right, height - y, paint, true, - mRenderer.getMarginsColor()); - drawBackground(mRenderer, canvas, x, y, left - x, height - y, paint, true, - mRenderer.getMarginsColor()); - } - - boolean showLabels = mRenderer.isShowLabels() && hasValues; - boolean showGridX = mRenderer.isShowGridX(); - boolean showCustomTextGrid = mRenderer.isShowCustomTextGrid(); - if (showLabels || showGridX) { - List xLabels = getValidLabels(getXLabels(minX[0], maxX[0], mRenderer.getXLabels())); - Map> allYLabels = getYLabels(minY, maxY, maxScaleNumber); - - int xLabelsLeft = left; - if (showLabels) { - paint.setColor(mRenderer.getXLabelsColor()); - paint.setTextSize(mRenderer.getLabelsTextSize()); - paint.setTextAlign(mRenderer.getXLabelsAlign()); - if (mRenderer.getXLabelsAlign() == Align.LEFT) { - xLabelsLeft += mRenderer.getLabelsTextSize() / 4; - } - } - drawXLabels(xLabels, mRenderer.getXTextLabelLocations(), canvas, paint, xLabelsLeft, top, - bottom, xPixelsPerUnit[0], minX[0], maxX[0]); - drawYLabels(allYLabels, canvas, paint, maxScaleNumber, left, right, bottom, yPixelsPerUnit, - minY); - - if (showLabels) { - paint.setColor(mRenderer.getLabelsColor()); - for (int i = 0; i < maxScaleNumber; i++) { - Align axisAlign = mRenderer.getYAxisAlign(i); - Double[] yTextLabelLocations = mRenderer.getYTextLabelLocations(i); - for (Double location : yTextLabelLocations) { - if (minY[i] <= location && location <= maxY[i]) { - float yLabel = (float) (bottom - yPixelsPerUnit[i] - * (location.doubleValue() - minY[i])); - String label = mRenderer.getYTextLabel(location, i); - paint.setColor(mRenderer.getYLabelsColor(i)); - paint.setTextAlign(mRenderer.getYLabelsAlign(i)); - if (or == Orientation.HORIZONTAL) { - if (axisAlign == Align.LEFT) { - canvas.drawLine(left + getLabelLinePos(axisAlign), yLabel, left, yLabel, paint); - drawText(canvas, label, left, yLabel - 2, paint, mRenderer.getYLabelsAngle()); - } else { - canvas.drawLine(right, yLabel, right + getLabelLinePos(axisAlign), yLabel, paint); - drawText(canvas, label, right, yLabel - 2, paint, mRenderer.getYLabelsAngle()); - } - - if (showCustomTextGrid) { - paint.setColor(mRenderer.getGridColor()); - canvas.drawLine(left, yLabel, right, yLabel, paint); - } - } else { - canvas.drawLine(right - getLabelLinePos(axisAlign), yLabel, right, yLabel, paint); - drawText(canvas, label, right + 10, yLabel - 2, paint, mRenderer.getYLabelsAngle()); - if (showCustomTextGrid) { - paint.setColor(mRenderer.getGridColor()); - canvas.drawLine(right, yLabel, left, yLabel, paint); - } - } - } - } - } - } - - if (showLabels) { - paint.setColor(mRenderer.getLabelsColor()); - float size = mRenderer.getAxisTitleTextSize(); - paint.setTextSize(size); - paint.setTextAlign(Align.CENTER); - if (or == Orientation.HORIZONTAL) { - drawText(canvas, mRenderer.getXTitle(), x + width / 2, - bottom + mRenderer.getLabelsTextSize() * 4 / 3 + size, paint, 0); - for (int i = 0; i < maxScaleNumber; i++) { - Align axisAlign = mRenderer.getYAxisAlign(i); - if (axisAlign == Align.LEFT) { - drawText(canvas, mRenderer.getYTitle(i), x + size, y + height / 2, paint, -90); - } else { - drawText(canvas, mRenderer.getYTitle(i), x + width, y + height / 2, paint, -90); - } - } - paint.setTextSize(mRenderer.getChartTitleTextSize()); - drawText(canvas, mRenderer.getChartTitle(), x + width / 2, - y + mRenderer.getChartTitleTextSize(), paint, 0); - } else if (or == Orientation.VERTICAL) { - drawText(canvas, mRenderer.getXTitle(), x + width / 2, y + height - size, paint, -90); - drawText(canvas, mRenderer.getYTitle(), right + 20, y + height / 2, paint, 0); - paint.setTextSize(mRenderer.getChartTitleTextSize()); - drawText(canvas, mRenderer.getChartTitle(), x + size, top + height / 2, paint, 0); - } - } - } - if (or == Orientation.HORIZONTAL) { - drawLegend(canvas, mRenderer, titles, left, right, y, width, height, legendSize, paint, false); - } else if (or == Orientation.VERTICAL) { - transform(canvas, angle, true); - drawLegend(canvas, mRenderer, titles, left, right, y, width, height, legendSize, paint, false); - transform(canvas, angle, false); - } - if (mRenderer.isShowAxes()) { - paint.setColor(mRenderer.getAxesColor()); - canvas.drawLine(left, bottom, right, bottom, paint); - boolean rightAxis = false; - for (int i = 0; i < maxScaleNumber && !rightAxis; i++) { - rightAxis = mRenderer.getYAxisAlign(i) == Align.RIGHT; - } - if (or == Orientation.HORIZONTAL) { - canvas.drawLine(left, top, left, bottom, paint); - if (rightAxis) { - canvas.drawLine(right, top, right, bottom, paint); - } - } else if (or == Orientation.VERTICAL) { - canvas.drawLine(right, top, right, bottom, paint); - } - } - if (rotate) { - transform(canvas, angle, true); - } - } - - protected List getXLabels(double min, double max, int count) { - return MathHelper.getLabels(min, max, count); - } - - protected Map> getYLabels(double[] minY, double[] maxY, int maxScaleNumber) { - Map> allYLabels = new HashMap>(); - for (int i = 0; i < maxScaleNumber; i++) { - allYLabels.put(i, - getValidLabels(MathHelper.getLabels(minY[i], maxY[i], mRenderer.getYLabels()))); - } - return allYLabels; - } - - protected Rect getScreenR() { - return mScreenR; - } - - protected void setScreenR(Rect screenR) { - mScreenR = screenR; - } - - private List getValidLabels(List labels) { - List result = new ArrayList(labels); - for (Double label : labels) { - if (label.isNaN()) { - result.remove(label); - } - } - return result; - } - - /** - * Draws the series. - * - * @param series the series - * @param canvas the canvas - * @param paint the paint object - * @param pointsList the points to be rendered - * @param seriesRenderer the series renderer - * @param yAxisValue the y axis value in pixels - * @param seriesIndex the series index - * @param or the orientation - * @param startIndex the start index of the rendering points - */ - protected void drawSeries(XYSeries series, Canvas canvas, Paint paint, List pointsList, - SimpleSeriesRenderer seriesRenderer, float yAxisValue, int seriesIndex, Orientation or, - int startIndex) { - BasicStroke stroke = seriesRenderer.getStroke(); - Cap cap = paint.getStrokeCap(); - Join join = paint.getStrokeJoin(); - float miter = paint.getStrokeMiter(); - PathEffect pathEffect = paint.getPathEffect(); - Style style = paint.getStyle(); - if (stroke != null) { - PathEffect effect = null; - if (stroke.getIntervals() != null) { - effect = new DashPathEffect(stroke.getIntervals(), stroke.getPhase()); - } - setStroke(stroke.getCap(), stroke.getJoin(), stroke.getMiter(), Style.FILL_AND_STROKE, - effect, paint); - } - float[] points = MathHelper.getFloats(pointsList); - drawSeries(canvas, paint, points, seriesRenderer, yAxisValue, seriesIndex, startIndex); - if (isRenderPoints(seriesRenderer)) { - ScatterChart pointsChart = getPointsChart(); - if (pointsChart != null) { - pointsChart.drawSeries(canvas, paint, points, seriesRenderer, yAxisValue, seriesIndex, - startIndex); - } - } - paint.setTextSize(seriesRenderer.getChartValuesTextSize()); - if (or == Orientation.HORIZONTAL) { - paint.setTextAlign(Align.CENTER); - } else { - paint.setTextAlign(Align.LEFT); - } - if (seriesRenderer.isDisplayChartValues()) { - paint.setTextAlign(seriesRenderer.getChartValuesTextAlign()); - drawChartValuesText(canvas, series, seriesRenderer, paint, points, seriesIndex, startIndex); - } - if (stroke != null) { - setStroke(cap, join, miter, style, pathEffect, paint); - } - } - - private void setStroke(Cap cap, Join join, float miter, Style style, PathEffect pathEffect, - Paint paint) { - paint.setStrokeCap(cap); - paint.setStrokeJoin(join); - paint.setStrokeMiter(miter); - paint.setPathEffect(pathEffect); - paint.setStyle(style); - } - - /** - * The graphical representation of the series values as text. - * - * @param canvas the canvas to paint to - * @param series the series to be painted - * @param renderer the series renderer - * @param paint the paint to be used for drawing - * @param points the array of points to be used for drawing the series - * @param seriesIndex the index of the series currently being drawn - * @param startIndex the start index of the rendering points - */ - protected void drawChartValuesText(Canvas canvas, XYSeries series, SimpleSeriesRenderer renderer, - Paint paint, float[] points, int seriesIndex, int startIndex) { - if (points.length > 1) { // there are more than one point - // record the first point's position - float previousPointX = points[0]; - float previousPointY = points[1]; - for (int k = 0; k < points.length; k += 2) { - if (k == 2) { // decide whether to display first two points' values or not - if (Math.abs(points[2]- points[0]) > 100 || Math.abs(points[3] - points[1]) > 100) { - // first point - drawText(canvas, getLabel(series.getY(startIndex)), points[0], points[1] - - renderer.getChartValuesSpacing(), paint, 0); - // second point - drawText(canvas, getLabel(series.getY(startIndex + 1)), points[2], points[3] - - renderer.getChartValuesSpacing(), paint, 0); - - previousPointX = points[2]; - previousPointY = points[3]; - } - } else if (k > 2) { - // compare current point's position with the previous point's, if they are not too close, display - if (Math.abs(points[k]- previousPointX) > 100 || Math.abs(points[k+1] - previousPointY) > 100) { - drawText(canvas, getLabel(series.getY(startIndex + k / 2)), points[k], points[k + 1] - - renderer.getChartValuesSpacing(), paint, 0); - previousPointX = points[k]; - previousPointY = points[k+1]; - } - } - } - } else { // if only one point, display it - for (int k = 0; k < points.length; k += 2) { - drawText(canvas, getLabel(series.getY(startIndex + k / 2)), points[k], points[k + 1] - - renderer.getChartValuesSpacing(), paint, 0); - } - } - } - - /** - * The graphical representation of a text, to handle both HORIZONTAL and - * VERTICAL orientations and extra rotation angles. - * - * @param canvas the canvas to paint to - * @param text the text to be rendered - * @param x the X axis location of the text - * @param y the Y axis location of the text - * @param paint the paint to be used for drawing - * @param extraAngle the text angle - */ - protected void drawText(Canvas canvas, String text, float x, float y, Paint paint, - float extraAngle) { - float angle = -mRenderer.getOrientation().getAngle() + extraAngle; - if (angle != 0) { - // canvas.scale(1 / mScale, mScale); - canvas.rotate(angle, x, y); - } - drawString(canvas, text, x, y, paint); - if (angle != 0) { - canvas.rotate(-angle, x, y); - // canvas.scale(mScale, 1 / mScale); - } - } - - /** - * Transform the canvas such as it can handle both HORIZONTAL and VERTICAL - * orientations. - * - * @param canvas the canvas to paint to - * @param angle the angle of rotation - * @param inverse if the inverse transform needs to be applied - */ - private void transform(Canvas canvas, float angle, boolean inverse) { - if (inverse) { - canvas.scale(1 / mScale, mScale); - canvas.translate(mTranslate, -mTranslate); - canvas.rotate(-angle, mCenter.getX(), mCenter.getY()); - } else { - canvas.rotate(angle, mCenter.getX(), mCenter.getY()); - canvas.translate(-mTranslate, mTranslate); - canvas.scale(mScale, 1 / mScale); - } - } - - /** - * The graphical representation of the labels on the X axis. - * - * @param xLabels the X labels values - * @param xTextLabelLocations the X text label locations - * @param canvas the canvas to paint to - * @param paint the paint to be used for drawing - * @param left the left value of the labels area - * @param top the top value of the labels area - * @param bottom the bottom value of the labels area - * @param xPixelsPerUnit the amount of pixels per one unit in the chart labels - * @param minX the minimum value on the X axis in the chart - * @param maxX the maximum value on the X axis in the chart - */ - protected void drawXLabels(List xLabels, Double[] xTextLabelLocations, Canvas canvas, - Paint paint, int left, int top, int bottom, double xPixelsPerUnit, double minX, double maxX) { - int length = xLabels.size(); - boolean showLabels = mRenderer.isShowLabels(); - boolean showGridY = mRenderer.isShowGridY(); - for (int i = 0; i < length; i++) { - double label = xLabels.get(i); - float xLabel = (float) (left + xPixelsPerUnit * (label - minX)); - if (showLabels) { - paint.setColor(mRenderer.getXLabelsColor()); - canvas.drawLine(xLabel, bottom, xLabel, bottom + mRenderer.getLabelsTextSize() / 3, paint); - drawText(canvas, getLabel(label), xLabel, bottom + mRenderer.getLabelsTextSize() * 4 / 3, - paint, mRenderer.getXLabelsAngle()); - } - if (showGridY) { - paint.setColor(mRenderer.getGridColor()); - canvas.drawLine(xLabel, bottom, xLabel, top, paint); - } - } - drawXTextLabels(xTextLabelLocations, canvas, paint, showLabels, left, top, bottom, - xPixelsPerUnit, minX, maxX); - } - - /** - * The graphical representation of the labels on the X axis. - * - * @param allYLabels the Y labels values - * @param canvas the canvas to paint to - * @param paint the paint to be used for drawing - * @param maxScaleNumber the maximum scale number - * @param left the left value of the labels area - * @param right the right value of the labels area - * @param bottom the bottom value of the labels area - * @param yPixelsPerUnit the amount of pixels per one unit in the chart labels - * @param minY the minimum value on the Y axis in the chart - */ - protected void drawYLabels(Map> allYLabels, Canvas canvas, Paint paint, - int maxScaleNumber, int left, int right, int bottom, double[] yPixelsPerUnit, double[] minY) { - Orientation or = mRenderer.getOrientation(); - boolean showGridX = mRenderer.isShowGridX(); - boolean showLabels = mRenderer.isShowLabels(); - for (int i = 0; i < maxScaleNumber; i++) { - paint.setTextAlign(mRenderer.getYLabelsAlign(i)); - List yLabels = allYLabels.get(i); - int length = yLabels.size(); - for (int j = 0; j < length; j++) { - double label = yLabels.get(j); - Align axisAlign = mRenderer.getYAxisAlign(i); - boolean textLabel = mRenderer.getYTextLabel(label, i) != null; - float yLabel = (float) (bottom - yPixelsPerUnit[i] * (label - minY[i])); - if (or == Orientation.HORIZONTAL) { - if (showLabels && !textLabel) { - paint.setColor(mRenderer.getYLabelsColor(i)); - if (axisAlign == Align.LEFT) { - canvas.drawLine(left + getLabelLinePos(axisAlign), yLabel, left, yLabel, paint); - drawText(canvas, getLabel(label), left, yLabel - 2, paint, - mRenderer.getYLabelsAngle()); - } else { - canvas.drawLine(right, yLabel, right + getLabelLinePos(axisAlign), yLabel, paint); - drawText(canvas, getLabel(label), right, yLabel - 2, paint, - mRenderer.getYLabelsAngle()); - } - } - if (showGridX) { - paint.setColor(mRenderer.getGridColor()); - canvas.drawLine(left, yLabel, right, yLabel, paint); - } - } else if (or == Orientation.VERTICAL) { - if (showLabels && !textLabel) { - paint.setColor(mRenderer.getYLabelsColor(i)); - canvas.drawLine(right - getLabelLinePos(axisAlign), yLabel, right, yLabel, paint); - drawText(canvas, getLabel(label), right + 10, yLabel - 2, paint, - mRenderer.getYLabelsAngle()); - } - if (showGridX) { - paint.setColor(mRenderer.getGridColor()); - canvas.drawLine(right, yLabel, left, yLabel, paint); - } - } - } - } - } - - /** - * The graphical representation of the text labels on the X axis. - * - * @param xTextLabelLocations the X text label locations - * @param canvas the canvas to paint to - * @param paint the paint to be used for drawing - * @param left the left value of the labels area - * @param top the top value of the labels area - * @param bottom the bottom value of the labels area - * @param xPixelsPerUnit the amount of pixels per one unit in the chart labels - * @param minX the minimum value on the X axis in the chart - * @param maxX the maximum value on the X axis in the chart - */ - protected void drawXTextLabels(Double[] xTextLabelLocations, Canvas canvas, Paint paint, - boolean showLabels, int left, int top, int bottom, double xPixelsPerUnit, double minX, - double maxX) { - boolean showCustomTextGrid = mRenderer.isShowCustomTextGrid(); - if (showLabels) { - paint.setColor(mRenderer.getXLabelsColor()); - for (Double location : xTextLabelLocations) { - if (minX <= location && location <= maxX) { - float xLabel = (float) (left + xPixelsPerUnit * (location.doubleValue() - minX)); - paint.setColor(mRenderer.getXLabelsColor()); - canvas - .drawLine(xLabel, bottom, xLabel, bottom + mRenderer.getLabelsTextSize() / 3, paint); - drawText(canvas, mRenderer.getXTextLabel(location), xLabel, - bottom + mRenderer.getLabelsTextSize() * 4 / 3, paint, mRenderer.getXLabelsAngle()); - if (showCustomTextGrid) { - paint.setColor(mRenderer.getGridColor()); - canvas.drawLine(xLabel, bottom, xLabel, top, paint); - } - } - } - } - } - - // TODO: docs - public XYMultipleSeriesRenderer getRenderer() { - return mRenderer; - } - - public XYMultipleSeriesDataset getDataset() { - return mDataset; - } - - public double[] getCalcRange(int scale) { - return mCalcRange.get(scale); - } - - public void setCalcRange(double[] range, int scale) { - mCalcRange.put(scale, range); - } - - public double[] toRealPoint(float screenX, float screenY) { - return toRealPoint(screenX, screenY, 0); - } - - public double[] toScreenPoint(double[] realPoint) { - return toScreenPoint(realPoint, 0); - } - - private int getLabelLinePos(Align align) { - int pos = 4; - if (align == Align.LEFT) { - pos = -pos; - } - return pos; - } - - /** - * Transforms a screen point to a real coordinates point. - * - * @param screenX the screen x axis value - * @param screenY the screen y axis value - * @return the real coordinates point - */ - public double[] toRealPoint(float screenX, float screenY, int scale) { - double realMinX = mRenderer.getXAxisMin(scale); - double realMaxX = mRenderer.getXAxisMax(scale); - double realMinY = mRenderer.getYAxisMin(scale); - double realMaxY = mRenderer.getYAxisMax(scale); - return new double[] { - (screenX - mScreenR.left) * (realMaxX - realMinX) / mScreenR.width() + realMinX, - (mScreenR.top + mScreenR.height() - screenY) * (realMaxY - realMinY) / mScreenR.height() - + realMinY }; - } - - public double[] toScreenPoint(double[] realPoint, int scale) { - double realMinX = mRenderer.getXAxisMin(scale); - double realMaxX = mRenderer.getXAxisMax(scale); - double realMinY = mRenderer.getYAxisMin(scale); - double realMaxY = mRenderer.getYAxisMax(scale); - if (!mRenderer.isMinXSet(scale) || !mRenderer.isMaxXSet(scale) || !mRenderer.isMinXSet(scale) - || !mRenderer.isMaxYSet(scale)) { - double[] calcRange = getCalcRange(scale); - realMinX = calcRange[0]; - realMaxX = calcRange[1]; - realMinY = calcRange[2]; - realMaxY = calcRange[3]; - } - return new double[] { - (realPoint[0] - realMinX) * mScreenR.width() / (realMaxX - realMinX) + mScreenR.left, - (realMaxY - realPoint[1]) * mScreenR.height() / (realMaxY - realMinY) + mScreenR.top }; - } - - public SeriesSelection getSeriesAndPointForScreenCoordinate(final Point screenPoint) { - if (clickableAreas != null) - for (int seriesIndex = clickableAreas.size() - 1; seriesIndex >= 0; seriesIndex--) { - // series 0 is drawn first. Then series 1 is drawn on top, and series 2 - // on top of that. - // we want to know what the user clicked on, so traverse them in the - // order they appear on the screen. - int pointIndex = 0; - if (clickableAreas.get(seriesIndex) != null) { - RectF rectangle; - for (ClickableArea area : clickableAreas.get(seriesIndex)) { - rectangle = area.getRect(); - if (rectangle != null && rectangle.contains(screenPoint.getX(), screenPoint.getY())) { - return new SeriesSelection(seriesIndex, pointIndex, area.getX(), area.getY()); - } - pointIndex++; - } - } - } - return super.getSeriesAndPointForScreenCoordinate(screenPoint); - } - - /** - * The graphical representation of a series. - * - * @param canvas the canvas to paint to - * @param paint the paint to be used for drawing - * @param points the array of points to be used for drawing the series - * @param seriesRenderer the series renderer - * @param yAxisValue the minimum value of the y axis - * @param seriesIndex the index of the series currently being drawn - * @param startIndex the start index of the rendering points - */ - public abstract void drawSeries(Canvas canvas, Paint paint, float[] points, - SimpleSeriesRenderer seriesRenderer, float yAxisValue, int seriesIndex, int startIndex); - - /** - * Returns the clickable areas for all passed points - * - * @param points the array of points - * @param values the array of values of each point - * @param yAxisValue the minimum value of the y axis - * @param seriesIndex the index of the series to which the points belong - * @return an array of rectangles with the clickable area - * @param startIndex the start index of the rendering points - */ - protected abstract ClickableArea[] clickableAreasForPoints(float[] points, double[] values, - float yAxisValue, int seriesIndex, int startIndex); - - /** - * Returns if the chart should display the null values. - * - * @return if null values should be rendered - */ - protected boolean isRenderNullValues() { - return false; - } - - /** - * Returns if the chart should display the points as a certain shape. - * - * @param renderer the series renderer - */ - public boolean isRenderPoints(SimpleSeriesRenderer renderer) { - return false; - } - - /** - * Returns the default axis minimum. - * - * @return the default axis minimum - */ - public double getDefaultMinimum() { - return MathHelper.NULL_VALUE; - } - - /** - * Returns the scatter chart to be used for drawing the data points. - * - * @return the data points scatter chart - */ - public ScatterChart getPointsChart() { - return null; - } - - /** - * Returns the chart type identifier. - * - * @return the chart type - */ - public abstract String getChartType(); - -} diff --git a/android-libraries/achartengine/src/org/achartengine/chart/package.html b/android-libraries/achartengine/src/org/achartengine/chart/package.html deleted file mode 100644 index 2c5fbec19..000000000 --- a/android-libraries/achartengine/src/org/achartengine/chart/package.html +++ /dev/null @@ -1,6 +0,0 @@ - -AChartEngine - -Provides the classes that handle the actual rendering / drawing of the charts, based on the provided model and renderer. - - \ No newline at end of file diff --git a/android-libraries/achartengine/src/org/achartengine/image/zoom-1.png b/android-libraries/achartengine/src/org/achartengine/image/zoom-1.png deleted file mode 100644 index 8265f27840a14b4b275086df67af01c73a3a8420..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1139 zcmV-(1dRKMP)iK~#9!wU*CoR96(oKljb}2AN4rGl?J?Uud%EMjJ&JKEVVG z!nl};q=TD^kVeR+1>N}r;}nZUq?AL44q-HL)Vj{^+{y=l%Wtq*5sw8X9PBZYGsVkw_$n#bU%_F%pRcb#-+llS$gz z+L)f6wq|E%zX*ch`+4NpV`KJXxh;Tlxtz~tvm82fh-5NJUtix}PRl|FK{lHu zm&+l9KnTI*%a^PEj*bp8nGBxiNLje2sXyh)6=tKT?j#U zcQ;BYwcv{TLv=2|x%z zJRV0Wg)s&pM0LJpN~!9aF@`9LkWvyw(LbvFdj*U0^YhhjU2Bcj8Yv}GN^-dzxm<2X zvaQ%K44ImmLMgRa6JU%Pe){w&zV8!;AzEvUF@#}A5CmwgQA!bpAz>JzltODw5CjB4 zK(SavYdu_3BFnN0g+k%$d_GTmdwW#|&+`yMaPQtdgb-9J6{M6q{BPgB<;jyL0EOLJ zg=5?H52sI`?!0^VF1BrBSr)c!BZSy-CQ7Ml%lPo&1J|!#XJTSv2+9UUeVdVy5ea+;%af{SP@!vXJ%)ntuV;yBK7U0vPNwY9Zh{xzVtw>Ncs zeEdS!^^)P?VQOk>C@n2T2!ZRm*tU&nntb^1f#=Vkv%0$KM5EE+gM))>vk4THp`oD% z*=+Ww$B!SEjE|2KkH?8bB2-mX5s$~IuC68)ixCco35Ub9w6tIthJ5qp&B(ob_kKJ* zJw3h=P$(3>({;URVq$`DI7~DerMkMBa5zjb7$gt~5C{Ya27^Q*5kjF5&CSj1?d{3^ z{r%4^%lhV101436)|PTzw`Xi@jPmkwqR}YvcpOdB2m}H=di02afdL;Pr6d#z(bUvL zI-SPzyq>D6s?@cBTrM|~N~Nf+ttAu+QBhHW5CSPBLj2h#Ap}AQA0nlst*wn@GKpar zBi8~f%hJ2MyU{d_NF;&~0?+gCJnt{gMcY-o5Q6^xew0%BrvN1YN~wnW`g(%FpdWl- zV89P>Wj1_3CX?~?`}gkyG~5J02ti3n2}&uHQh1){!#9vmD5V19lc$8k_fVVWkkZBr-|*xlVlDRp>l4?NFXSz21c zG))SH0+wY_C=`6%bzNN7^=+nUVi*RNWnozsi;Ii6uDfzAKuVd(WHMy4Sq#GRMv$L~knue4TP1F272qFCb6j#Q@ z#RZd-lWc8mEd#wbP4aJ2%B`cLqpv=G{3zSo+x_Mh%VijbU!HtE&)L}-Gcz-+uC6-3 z*Fg5hRpGj>CWKht-Q6A8+}xD)_4SmMmHEMo^*%p8XM1~_>FH@+zkclidEiUn6!`hJ zb)5iWLWpNl%ASW0AJWy;MPp+l00##Lyn6MDmoHxeECWx07rQWzN|_ygF>@YIfg RUN-;$002ovPDHLkV1jl}0RjL3 diff --git a/android-libraries/achartengine/src/org/achartengine/image/zoom_out.png b/android-libraries/achartengine/src/org/achartengine/image/zoom_out.png deleted file mode 100644 index d67a87de533e307cb0e95ab2623259d98eb1adae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1074 zcmV-21kL-2P)ZcG>Ma%D2N{kj*D)b>fpvF=zwm5 z5E-mXbGYn7^T$p^GpsN-Jnrg5T1P7C|(AOa;G)2(2OS^S;-Oc{m-T zrPvDx4(A=t@1Aow=RWwKkErw^ola*8g~FI=nwsM{ZAvMCBVg&#qer>*_4ObB6JUIN z{ORWA=36P{z~JB@Po6v>9*^U?E`>sYwY4>7XJ>I7XTG_)`Q_^B>TmxV@a);M%<1Xr zdri}-Mn^|!Y;2^ux*8z_uIpmkHiltva&p4EckftUUUp)!*y#TLe#LA8Wo2Y!N*^MnBpeRY-ri0&o5l0I zf%^LTOhrJUP#DW(GBh^|6Wo(=@fdzCMD% zAkk$*6OgHj5^FtBYK%d*(n*+D6FRIvx1=Pk|6&0!b@mStg@CYELSdRfXg!!Xcw z-M7!q&f>c6QbmB2GMCHc$mjFux=yK7Lf7?A#57GxrIIhEX`<^o+uPgB%*+7fDh`@u zS%wgz`{3XpH8?nk>$+H$<*x_JvaoI2&!P+~7K^-k^@_8zvw2|Zu1Wq=O8NWo@$on3 z=jXD!yW4MGIjFAdetAlz5?5DOym|A6<>h4u_zuY5xhh=O4GJOVcXoEhK79BfTU%SH zsj2aUm+M_D7TMa`;`Qs-tgNg!KneI7xCDN^Z(S#WxDev4lyacIzn|XTUQ($P0Q>v< zEG{mxu&@9y54;5417BQU_5%18`02g}CkcE7i~-t>AvywFLpdzpl%ce8{Ia30zH0O({*&9N-ElJ|v`^m66S6?PM}( sKQ!Pb mCategories = new ArrayList(); - /** The series values. */ - private List mValues = new ArrayList(); - - /** - * Builds a new category series. - * - * @param title the series title - */ - public CategorySeries(String title) { - mTitle = title; - } - - /** - * Returns the series title. - * - * @return the series title - */ - public String getTitle() { - return mTitle; - } - - /** - * Adds a new value to the series - * - * @param value the new value - */ - public synchronized void add(double value) { - add(mCategories.size() + "", value); - } - - /** - * Adds a new value to the series. - * - * @param category the category - * @param value the new value - */ - public synchronized void add(String category, double value) { - mCategories.add(category); - mValues.add(value); - } - - /** - * Replaces the value at the specific index in the series. - * - * @param index the index in the series - * @param category the category - * @param value the new value - */ - public synchronized void set(int index, String category, double value) { - mCategories.set(index, category); - mValues.set(index, value); - } - - /** - * Removes an existing value from the series. - * - * @param index the index in the series of the value to remove - */ - public synchronized void remove(int index) { - mCategories.remove(index); - mValues.remove(index); - } - - /** - * Removes all the existing values from the series. - */ - public synchronized void clear() { - mCategories.clear(); - mValues.clear(); - } - - /** - * Returns the value at the specified index. - * - * @param index the index - * @return the value at the index - */ - public synchronized double getValue(int index) { - return mValues.get(index); - } - - /** - * Returns the category name at the specified index. - * - * @param index the index - * @return the category name at the index - */ - public synchronized String getCategory(int index) { - return mCategories.get(index); - } - - /** - * Returns the series item count. - * - * @return the series item count - */ - public synchronized int getItemCount() { - return mCategories.size(); - } - - /** - * Transforms the category series to an XY series. - * - * @return the XY series - */ - public XYSeries toXYSeries() { - XYSeries xySeries = new XYSeries(mTitle); - int k = 0; - for (double value : mValues) { - xySeries.add(++k, value); - } - return xySeries; - } -} diff --git a/android-libraries/achartengine/src/org/achartengine/model/MultipleCategorySeries.java b/android-libraries/achartengine/src/org/achartengine/model/MultipleCategorySeries.java deleted file mode 100644 index 992db4c17..000000000 --- a/android-libraries/achartengine/src/org/achartengine/model/MultipleCategorySeries.java +++ /dev/null @@ -1,145 +0,0 @@ -/** - * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.achartengine.model; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - -/** - * A series for the multiple category charts like the doughnut. - */ -public class MultipleCategorySeries implements Serializable { - /** The series title. */ - private String mTitle; - /** The series local keys. */ - private List mCategories = new ArrayList(); - /** The series name. */ - private List mTitles = new ArrayList(); - /** The series values. */ - private List mValues = new ArrayList(); - - /** - * Builds a new category series. - * - * @param title the series title - */ - public MultipleCategorySeries(String title) { - mTitle = title; - } - - /** - * Adds a new value to the series - * - * @param titles the titles to be used as labels - * @param values the new value - */ - public void add(String[] titles, double[] values) { - add(mCategories.size() + "", titles, values); - } - - /** - * Adds a new value to the series. - * - * @param category the category name - * @param titles the titles to be used as labels - * @param values the new value - */ - public void add(String category, String[] titles, double[] values) { - mCategories.add(category); - mTitles.add(titles); - mValues.add(values); - } - - /** - * Removes an existing value from the series. - * - * @param index the index in the series of the value to remove - */ - public void remove(int index) { - mCategories.remove(index); - mTitles.remove(index); - mValues.remove(index); - } - - /** - * Removes all the existing values from the series. - */ - public void clear() { - mCategories.clear(); - mTitles.clear(); - mValues.clear(); - } - - /** - * Returns the values at the specified index. - * - * @param index the index - * @return the value at the index - */ - public double[] getValues(int index) { - return mValues.get(index); - } - - /** - * Returns the category name at the specified index. - * - * @param index the index - * @return the category name at the index - */ - public String getCategory(int index) { - return mCategories.get(index); - } - - /** - * Returns the categories count. - * - * @return the categories count - */ - public int getCategoriesCount() { - return mCategories.size(); - } - - /** - * Returns the series item count. - * - * @param index the index - * @return the series item count - */ - public int getItemCount(int index) { - return mValues.get(index).length; - } - - /** - * Returns the series titles. - * - * @param index the index - * @return the series titles - */ - public String[] getTitles(int index) { - return mTitles.get(index); - } - - /** - * Transforms the category series to an XY series. - * - * @return the XY series - */ - public XYSeries toXYSeries() { - XYSeries xySeries = new XYSeries(mTitle); - return xySeries; - } -} diff --git a/android-libraries/achartengine/src/org/achartengine/model/Point.java b/android-libraries/achartengine/src/org/achartengine/model/Point.java deleted file mode 100644 index 4d2767cf8..000000000 --- a/android-libraries/achartengine/src/org/achartengine/model/Point.java +++ /dev/null @@ -1,52 +0,0 @@ -/** - * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.achartengine.model; - -import java.io.Serializable; - -/** - * A class to encapsulate the definition of a point. - */ -public final class Point implements Serializable { - /** The X axis coordinate value. */ - private float mX; - /** The Y axis coordinate value. */ - private float mY; - - public Point() { - } - - public Point(float x, float y) { - mX = x; - mY = y; - } - - public float getX() { - return mX; - } - - public float getY() { - return mY; - } - - public void setX(float x) { - mX = x; - } - - public void setY(float y) { - mY = y; - } -} diff --git a/android-libraries/achartengine/src/org/achartengine/model/RangeCategorySeries.java b/android-libraries/achartengine/src/org/achartengine/model/RangeCategorySeries.java deleted file mode 100644 index c004fa106..000000000 --- a/android-libraries/achartengine/src/org/achartengine/model/RangeCategorySeries.java +++ /dev/null @@ -1,111 +0,0 @@ -/** - * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.achartengine.model; - -import java.util.ArrayList; -import java.util.List; -/** - * A series for the range category charts like the range bar. - */ -public class RangeCategorySeries extends CategorySeries { - /** The series values. */ - private List mMaxValues = new ArrayList(); - /** - * Builds a new category series. - * - * @param title the series title - */ - public RangeCategorySeries(String title) { - super(title); - } - /** - * Adds new values to the series - * - * @param minValue the new minimum value - * @param maxValue the new maximum value - */ - public synchronized void add(double minValue, double maxValue) { - super.add(minValue); - mMaxValues.add(maxValue); - } - - /** - * Adds new values to the series. - * - * @param category the category - * @param minValue the new minimum value - * @param maxValue the new maximum value - */ - public synchronized void add(String category, double minValue, double maxValue) { - super.add(category, minValue); - mMaxValues.add(maxValue); - } - - /** - * Removes existing values from the series. - * - * @param index the index in the series of the values to remove - */ - public synchronized void remove(int index) { - super.remove(index); - mMaxValues.remove(index); - } - - /** - * Removes all the existing values from the series. - */ - public synchronized void clear() { - super.clear(); - mMaxValues.clear(); - } - - /** - * Returns the minimum value at the specified index. - * - * @param index the index - * @return the minimum value at the index - */ - public double getMinimumValue(int index) { - return getValue(index); - } - - /** - * Returns the maximum value at the specified index. - * - * @param index the index - * @return the maximum value at the index - */ - public double getMaximumValue(int index) { - return mMaxValues.get(index); - } - - /** - * Transforms the range category series to an XY series. - * - * @return the XY series - */ - public XYSeries toXYSeries() { - XYSeries xySeries = new XYSeries(getTitle()); - int length = getItemCount(); - for (int k = 0; k < length; k++) { - xySeries.add(k + 1, getMinimumValue(k)); - // the new fast XYSeries implementation doesn't allow 2 values at the same X, - // so I had to do a hack until I find a better solution - xySeries.add(k + 1.000001, getMaximumValue(k)); - } - return xySeries; - } -} diff --git a/android-libraries/achartengine/src/org/achartengine/model/SeriesSelection.java b/android-libraries/achartengine/src/org/achartengine/model/SeriesSelection.java deleted file mode 100644 index 4319c742b..000000000 --- a/android-libraries/achartengine/src/org/achartengine/model/SeriesSelection.java +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.achartengine.model; - -public class SeriesSelection { - private int mSeriesIndex; - - private int mPointIndex; - - private double mXValue; - - private double mValue; - - public SeriesSelection(int seriesIndex, int pointIndex, double xValue, double value) { - mSeriesIndex = seriesIndex; - mPointIndex = pointIndex; - mXValue = xValue; - mValue = value; - } - - public int getSeriesIndex() { - return mSeriesIndex; - } - - public int getPointIndex() { - return mPointIndex; - } - - public double getXValue() { - return mXValue; - } - - public double getValue() { - return mValue; - } -} \ No newline at end of file diff --git a/android-libraries/achartengine/src/org/achartengine/model/TimeSeries.java b/android-libraries/achartengine/src/org/achartengine/model/TimeSeries.java deleted file mode 100644 index 6b9a18e5c..000000000 --- a/android-libraries/achartengine/src/org/achartengine/model/TimeSeries.java +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.achartengine.model; - -import java.util.Date; - -/** - * A series for the date / time charts. - */ -public class TimeSeries extends XYSeries { - - /** - * Builds a new date / time series. - * - * @param title the series title - */ - public TimeSeries(String title) { - super(title); - } - - /** - * Adds a new value to the series. - * - * @param x the date / time value for the X axis - * @param y the value for the Y axis - */ - public synchronized void add(Date x, double y) { - super.add(x.getTime(), y); - } -} diff --git a/android-libraries/achartengine/src/org/achartengine/model/XYMultipleSeriesDataset.java b/android-libraries/achartengine/src/org/achartengine/model/XYMultipleSeriesDataset.java deleted file mode 100644 index 6ac6a6def..000000000 --- a/android-libraries/achartengine/src/org/achartengine/model/XYMultipleSeriesDataset.java +++ /dev/null @@ -1,94 +0,0 @@ -/** - * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.achartengine.model; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - -/** - * A series that includes 0 to many XYSeries. - */ -public class XYMultipleSeriesDataset implements Serializable { - /** The included series. */ - private List mSeries = new ArrayList(); - - /** - * Adds a new XY series to the list. - * - * @param series the XY series to ass - */ - public synchronized void addSeries(XYSeries series) { - mSeries.add(series); - } - - /** - * Adds a new XY series to the list. - * - * @param index the index in the series list - * @param series the XY series to ass - */ - public synchronized void addSeries(int index, XYSeries series) { - mSeries.add(index, series); - } - - /** - * Removes the XY series from the list. - * - * @param index the index in the series list of the series to remove - */ - public synchronized void removeSeries(int index) { - mSeries.remove(index); - } - - /** - * Removes the XY series from the list. - * - * @param series the XY series to be removed - */ - public synchronized void removeSeries(XYSeries series) { - mSeries.remove(series); - } - - /** - * Returns the XY series at the specified index. - * - * @param index the index - * @return the XY series at the index - */ - public synchronized XYSeries getSeriesAt(int index) { - return mSeries.get(index); - } - - /** - * Returns the XY series count. - * - * @return the XY series count - */ - public synchronized int getSeriesCount() { - return mSeries.size(); - } - - /** - * Returns an array of the XY series. - * - * @return the XY series array - */ - public synchronized XYSeries[] getSeries() { - return mSeries.toArray(new XYSeries[0]); - } - -} diff --git a/android-libraries/achartengine/src/org/achartengine/model/XYSeries.java b/android-libraries/achartengine/src/org/achartengine/model/XYSeries.java deleted file mode 100644 index 56063b77e..000000000 --- a/android-libraries/achartengine/src/org/achartengine/model/XYSeries.java +++ /dev/null @@ -1,255 +0,0 @@ -/** - * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.achartengine.model; - -import java.io.Serializable; -import java.util.Iterator; -import java.util.SortedMap; - -import org.achartengine.util.IndexXYMap; -import org.achartengine.util.MathHelper; -import org.achartengine.util.XYEntry; - -/** - * An XY series encapsulates values for XY charts like line, time, area, - * scatter... charts. - */ -public class XYSeries implements Serializable { - /** The series title. */ - private String mTitle; - /** A map to contain values for X and Y axes and index for each bundle */ - private final IndexXYMap mXY = new IndexXYMap(); - /** The minimum value for the X axis. */ - private double mMinX = MathHelper.NULL_VALUE; - /** The maximum value for the X axis. */ - private double mMaxX = -MathHelper.NULL_VALUE; - /** The minimum value for the Y axis. */ - private double mMinY = MathHelper.NULL_VALUE; - /** The maximum value for the Y axis. */ - private double mMaxY = -MathHelper.NULL_VALUE; - /** The scale number for this series. */ - private final int mScaleNumber; - - /** - * Builds a new XY series. - * - * @param title the series title. - */ - public XYSeries(String title) { - this(title, 0); - } - - /** - * Builds a new XY series. - * - * @param title the series title. - * @param scaleNumber the series scale number - */ - public XYSeries(String title, int scaleNumber) { - mTitle = title; - mScaleNumber = scaleNumber; - initRange(); - } - - public int getScaleNumber() { - return mScaleNumber; - } - - /** - * Initializes the range for both axes. - */ - private void initRange() { - mMinX = MathHelper.NULL_VALUE; - mMaxX = -MathHelper.NULL_VALUE; - mMinY = MathHelper.NULL_VALUE; - mMaxY = -MathHelper.NULL_VALUE; - int length = getItemCount(); - for (int k = 0; k < length; k++) { - double x = getX(k); - double y = getY(k); - updateRange(x, y); - } - } - - /** - * Updates the range on both axes. - * - * @param x the new x value - * @param y the new y value - */ - private void updateRange(double x, double y) { - mMinX = Math.min(mMinX, x); - mMaxX = Math.max(mMaxX, x); - mMinY = Math.min(mMinY, y); - mMaxY = Math.max(mMaxY, y); - } - - /** - * Returns the series title. - * - * @return the series title - */ - public String getTitle() { - return mTitle; - } - - /** - * Sets the series title. - * - * @param title the series title - */ - public void setTitle(String title) { - mTitle = title; - } - - /** - * Adds a new value to the series. - * - * @param x the value for the X axis - * @param y the value for the Y axis - */ - public synchronized void add(double x, double y) { - mXY.put(x, y); - updateRange(x, y); - } - - /** - * Removes an existing value from the series. - * - * @param index the index in the series of the value to remove - */ - public synchronized void remove(int index) { - XYEntry removedEntry = mXY.removeByIndex(index); - double removedX = removedEntry.getKey(); - double removedY = removedEntry.getValue(); - if (removedX == mMinX || removedX == mMaxX || removedY == mMinY || removedY == mMaxY) { - initRange(); - } - } - - /** - * Removes all the existing values from the series. - */ - public synchronized void clear() { - mXY.clear(); - initRange(); - } - - /** - * Returns the X axis value at the specified index. - * - * @param index the index - * @return the X value - */ - public synchronized double getX(int index) { - return mXY.getXByIndex(index); - } - - /** - * Returns the Y axis value at the specified index. - * - * @param index the index - * @return the Y value - */ - public synchronized double getY(int index) { - return mXY.getYByIndex(index); - } - - /** - * Returns submap of x and y values according to the given start and end - * - * @param start start x value - * @param stop stop x value - * @return a submap of x and y values - */ - public synchronized SortedMap getRange(double start, double stop, - int beforeAfterPoints) { - // we need to add one point before the start and one point after the end (if - // there are any) - // to ensure that line doesn't end before the end of the screen - - // this would be simply: start = mXY.lowerKey(start) but NavigableMap is - // available since API 9 - SortedMap headMap = mXY.headMap(start); - if (!headMap.isEmpty()) { - start = headMap.lastKey(); - } - - // this would be simply: end = mXY.higherKey(end) but NavigableMap is - // available since API 9 - // so we have to do this hack in order to support older versions - SortedMap tailMap = mXY.tailMap(stop); - if (!tailMap.isEmpty()) { - Iterator tailIterator = tailMap.keySet().iterator(); - Double next = tailIterator.next(); - if (tailIterator.hasNext()) { - stop = tailIterator.next(); - } else { - stop += next; - } - } - return mXY.subMap(start, stop); - } - - public int getIndexForKey(double key) { - return mXY.getIndexForKey(key); - } - - /** - * Returns the series item count. - * - * @return the series item count - */ - public synchronized int getItemCount() { - return mXY.size(); - } - - /** - * Returns the minimum value on the X axis. - * - * @return the X axis minimum value - */ - public double getMinX() { - return mMinX; - } - - /** - * Returns the minimum value on the Y axis. - * - * @return the Y axis minimum value - */ - public double getMinY() { - return mMinY; - } - - /** - * Returns the maximum value on the X axis. - * - * @return the X axis maximum value - */ - public double getMaxX() { - return mMaxX; - } - - /** - * Returns the maximum value on the Y axis. - * - * @return the Y axis maximum value - */ - public double getMaxY() { - return mMaxY; - } -} diff --git a/android-libraries/achartengine/src/org/achartengine/model/XYValueSeries.java b/android-libraries/achartengine/src/org/achartengine/model/XYValueSeries.java deleted file mode 100644 index 81aff28b8..000000000 --- a/android-libraries/achartengine/src/org/achartengine/model/XYValueSeries.java +++ /dev/null @@ -1,139 +0,0 @@ -/** - * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.achartengine.model; - -import java.util.ArrayList; -import java.util.List; - -import org.achartengine.util.MathHelper; - -/** - * An extension of the XY series which adds a third dimension. It is used for XY - * charts like bubble. - */ -public class XYValueSeries extends XYSeries { - /** A list to contain the series values. */ - private List mValue = new ArrayList(); - /** The minimum value. */ - private double mMinValue = MathHelper.NULL_VALUE; - /** The maximum value. */ - private double mMaxValue = -MathHelper.NULL_VALUE; - - /** - * Builds a new XY value series. - * - * @param title the series title. - */ - public XYValueSeries(String title) { - super(title); - } - - /** - * Adds a new value to the series. - * - * @param x the value for the X axis - * @param y the value for the Y axis - * @param value the value - */ - public synchronized void add(double x, double y, double value) { - super.add(x, y); - mValue.add(value); - updateRange(value); - } - - /** - * Initializes the values range. - */ - private void initRange() { - mMinValue = MathHelper.NULL_VALUE; - mMaxValue = MathHelper.NULL_VALUE; - int length = getItemCount(); - for (int k = 0; k < length; k++) { - updateRange(getValue(k)); - } - } - - /** - * Updates the values range. - * - * @param value the new value - */ - private void updateRange(double value) { - mMinValue = Math.min(mMinValue, value); - mMaxValue = Math.max(mMaxValue, value); - } - - /** - * Adds a new value to the series. - * - * @param x the value for the X axis - * @param y the value for the Y axis - */ - public synchronized void add(double x, double y) { - add(x, y, 0d); - } - - /** - * Removes an existing value from the series. - * - * @param index the index in the series of the value to remove - */ - public synchronized void remove(int index) { - super.remove(index); - double removedValue = mValue.remove(index); - if (removedValue == mMinValue || removedValue == mMaxValue) { - initRange(); - } - } - - /** - * Removes all the values from the series. - */ - public synchronized void clear() { - super.clear(); - mValue.clear(); - initRange(); - } - - /** - * Returns the value at the specified index. - * - * @param index the index - * @return the value - */ - public synchronized double getValue(int index) { - return mValue.get(index); - } - - /** - * Returns the minimum value. - * - * @return the minimum value - */ - public double getMinValue() { - return mMinValue; - } - - /** - * Returns the maximum value. - * - * @return the maximum value - */ - public double getMaxValue() { - return mMaxValue; - } - -} diff --git a/android-libraries/achartengine/src/org/achartengine/model/package.html b/android-libraries/achartengine/src/org/achartengine/model/package.html deleted file mode 100644 index 6135d29c7..000000000 --- a/android-libraries/achartengine/src/org/achartengine/model/package.html +++ /dev/null @@ -1,6 +0,0 @@ - -AChartEngine - -Provides the classes that handle the data values (data model) to be used by displaying the charts. - - \ No newline at end of file diff --git a/android-libraries/achartengine/src/org/achartengine/package.html b/android-libraries/achartengine/src/org/achartengine/package.html deleted file mode 100644 index b26cf259e..000000000 --- a/android-libraries/achartengine/src/org/achartengine/package.html +++ /dev/null @@ -1,6 +0,0 @@ - -AChartEngine - -The main classes, including the ChartFactory, GraphicalActivity and GraphicalView. - - \ No newline at end of file diff --git a/android-libraries/achartengine/src/org/achartengine/renderer/BasicStroke.java b/android-libraries/achartengine/src/org/achartengine/renderer/BasicStroke.java deleted file mode 100644 index 3ac93d54e..000000000 --- a/android-libraries/achartengine/src/org/achartengine/renderer/BasicStroke.java +++ /dev/null @@ -1,107 +0,0 @@ -/** - * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.achartengine.renderer; - -import java.io.Serializable; - -import android.graphics.Paint.Cap; -import android.graphics.Paint.Join; - -/** - * A descriptor for the stroke style. - */ -public class BasicStroke implements Serializable { - /** The solid line style. */ - public static final BasicStroke SOLID = new BasicStroke(Cap.BUTT, Join.MITER, 4, null, 0); - /** The dashed line style. */ - public static final BasicStroke DASHED = new BasicStroke(Cap.ROUND, Join.BEVEL, 10, new float[] { - 10, 10 }, 1); - /** The dot line style. */ - public static final BasicStroke DOTTED = new BasicStroke(Cap.ROUND, Join.BEVEL, 5, new float[] { - 2, 10 }, 1); - /** The stroke cap. */ - private Cap mCap; - /** The stroke join. */ - private Join mJoin; - /** The stroke miter. */ - private float mMiter; - /** The path effect intervals. */ - private float[] mIntervals; - /** The path effect phase. */ - private float mPhase; - - /** - * Build a new basic stroke style. - * - * @param cap the stroke cap - * @param join the stroke join - * @param miter the stroke miter - * @param intervals the path effect intervals - * @param phase the path effect phase - */ - public BasicStroke(Cap cap, Join join, float miter, float[] intervals, float phase) { - mCap = cap; - mJoin = join; - mMiter = miter; - mIntervals = intervals; - } - - /** - * Returns the stroke cap. - * - * @return the stroke cap - */ - public Cap getCap() { - return mCap; - } - - /** - * Returns the stroke join. - * - * @return the stroke join - */ - public Join getJoin() { - return mJoin; - } - - /** - * Returns the stroke miter. - * - * @return the stroke miter - */ - public float getMiter() { - return mMiter; - } - - /** - * Returns the path effect intervals. - * - * @return the path effect intervals - */ - public float[] getIntervals() { - return mIntervals; - } - - /** - * Returns the path effect phase. - * - * @return the path effect phase - */ - public float getPhase() { - return mPhase; - } - -} diff --git a/android-libraries/achartengine/src/org/achartengine/renderer/DefaultRenderer.java b/android-libraries/achartengine/src/org/achartengine/renderer/DefaultRenderer.java deleted file mode 100644 index 4dbb25497..000000000 --- a/android-libraries/achartengine/src/org/achartengine/renderer/DefaultRenderer.java +++ /dev/null @@ -1,750 +0,0 @@ -/** - * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.achartengine.renderer; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - -import android.graphics.Color; -import android.graphics.Typeface; - -/** - * An abstract renderer to be extended by the multiple series classes. - */ -public class DefaultRenderer implements Serializable { - /** The chart title. */ - private String mChartTitle = ""; - /** The chart title text size. */ - private float mChartTitleTextSize = 15; - /** A no color constant. */ - public static final int NO_COLOR = 0; - /** The default background color. */ - public static final int BACKGROUND_COLOR = Color.BLACK; - /** The default color for text. */ - public static final int TEXT_COLOR = Color.LTGRAY; - /** A text font for regular text, like the chart labels. */ - private static final Typeface REGULAR_TEXT_FONT = Typeface - .create(Typeface.SERIF, Typeface.NORMAL); - /** The typeface name for the texts. */ - private String mTextTypefaceName = REGULAR_TEXT_FONT.toString(); - /** The typeface style for the texts. */ - private int mTextTypefaceStyle = Typeface.NORMAL; - /** The chart background color. */ - private int mBackgroundColor; - /** If the background color is applied. */ - private boolean mApplyBackgroundColor; - /** If the axes are visible. */ - private boolean mShowAxes = true; - /** The axes color. */ - private int mAxesColor = TEXT_COLOR; - /** If the labels are visible. */ - private boolean mShowLabels = true; - /** The labels color. */ - private int mLabelsColor = TEXT_COLOR; - /** The labels text size. */ - private float mLabelsTextSize = 10; - /** If the legend is visible. */ - private boolean mShowLegend = true; - /** The legend text size. */ - private float mLegendTextSize = 12; - /** If the legend should size to fit. */ - private boolean mFitLegend = false; - /** If the X axis grid should be displayed. */ - private boolean mShowGridX = false; - /** If the Y axis grid should be displayed. */ - private boolean mShowGridY = false; - /** If the custom text grid should be displayed. */ - private boolean mShowCustomTextGrid = false; - /** The simple renderers that are included in this multiple series renderer. */ - private List mRenderers = new ArrayList(); - /** The antialiasing flag. */ - private boolean mAntialiasing = true; - /** The legend height. */ - private int mLegendHeight = 0; - /** The margins size. */ - private int[] mMargins = new int[] { 20, 30, 10, 20 }; - /** A value to be used for scaling the chart. */ - private float mScale = 1; - /** A flag for enabling the pan. */ - private boolean mPanEnabled = true; - /** A flag for enabling the zoom. */ - private boolean mZoomEnabled = true; - /** A flag for enabling the visibility of the zoom buttons. */ - private boolean mZoomButtonsVisible = false; - /** The zoom rate. */ - private float mZoomRate = 1.5f; - /** A flag for enabling the external zoom. */ - private boolean mExternalZoomEnabled = false; - /** The original chart scale. */ - private float mOriginalScale = mScale; - /** A flag for enabling the click on elements. */ - private boolean mClickEnabled = false; - /** The selectable radius around a clickable point. */ - private int selectableBuffer = 15; - /** If the chart should display the values (available for pie chart). */ - private boolean mDisplayValues; - - /** - * A flag to be set if the chart is inside a scroll and doesn't need to shrink - * when not enough space. - */ - private boolean mInScroll; - /** The start angle for circular charts such as pie, doughnut, etc. */ - private float mStartAngle = 0; - - /** - * Returns the chart title. - * - * @return the chart title - */ - public String getChartTitle() { - return mChartTitle; - } - - /** - * Sets the chart title. - * - * @param title the chart title - */ - public void setChartTitle(String title) { - mChartTitle = title; - } - - /** - * Returns the chart title text size. - * - * @return the chart title text size - */ - public float getChartTitleTextSize() { - return mChartTitleTextSize; - } - - /** - * Sets the chart title text size. - * - * @param textSize the chart title text size - */ - public void setChartTitleTextSize(float textSize) { - mChartTitleTextSize = textSize; - } - - /** - * Adds a simple renderer to the multiple renderer. - * - * @param renderer the renderer to be added - */ - public void addSeriesRenderer(SimpleSeriesRenderer renderer) { - mRenderers.add(renderer); - } - - /** - * Adds a simple renderer to the multiple renderer. - * - * @param index the index in the renderers list - * @param renderer the renderer to be added - */ - public void addSeriesRenderer(int index, SimpleSeriesRenderer renderer) { - mRenderers.add(index, renderer); - } - - /** - * Removes a simple renderer from the multiple renderer. - * - * @param renderer the renderer to be removed - */ - public void removeSeriesRenderer(SimpleSeriesRenderer renderer) { - mRenderers.remove(renderer); - } - - /** - * Removes all renderers from the multiple renderer. - */ - public void removeAllRenderers() { - mRenderers.clear(); - } - - /** - * Returns the simple renderer from the multiple renderer list. - * - * @param index the index in the simple renderers list - * @return the simple renderer at the specified index - */ - public SimpleSeriesRenderer getSeriesRendererAt(int index) { - return mRenderers.get(index); - } - - /** - * Returns the simple renderers count in the multiple renderer list. - * - * @return the simple renderers count - */ - public int getSeriesRendererCount() { - return mRenderers.size(); - } - - /** - * Returns an array of the simple renderers in the multiple renderer list. - * - * @return the simple renderers array - */ - public SimpleSeriesRenderer[] getSeriesRenderers() { - return mRenderers.toArray(new SimpleSeriesRenderer[0]); - } - - /** - * Returns the background color. - * - * @return the background color - */ - public int getBackgroundColor() { - return mBackgroundColor; - } - - /** - * Sets the background color. - * - * @param color the background color - */ - public void setBackgroundColor(int color) { - mBackgroundColor = color; - } - - /** - * Returns if the background color should be applied. - * - * @return the apply flag for the background color. - */ - public boolean isApplyBackgroundColor() { - return mApplyBackgroundColor; - } - - /** - * Sets if the background color should be applied. - * - * @param apply the apply flag for the background color - */ - public void setApplyBackgroundColor(boolean apply) { - mApplyBackgroundColor = apply; - } - - /** - * Returns the axes color. - * - * @return the axes color - */ - public int getAxesColor() { - return mAxesColor; - } - - /** - * Sets the axes color. - * - * @param color the axes color - */ - public void setAxesColor(int color) { - mAxesColor = color; - } - - /** - * Returns the labels color. - * - * @return the labels color - */ - public int getLabelsColor() { - return mLabelsColor; - } - - /** - * Sets the labels color. - * - * @param color the labels color - */ - public void setLabelsColor(int color) { - mLabelsColor = color; - } - - /** - * Returns the labels text size. - * - * @return the labels text size - */ - public float getLabelsTextSize() { - return mLabelsTextSize; - } - - /** - * Sets the labels text size. - * - * @param textSize the labels text size - */ - public void setLabelsTextSize(float textSize) { - mLabelsTextSize = textSize; - } - - /** - * Returns if the axes should be visible. - * - * @return the visibility flag for the axes - */ - public boolean isShowAxes() { - return mShowAxes; - } - - /** - * Sets if the axes should be visible. - * - * @param showAxes the visibility flag for the axes - */ - public void setShowAxes(boolean showAxes) { - mShowAxes = showAxes; - } - - /** - * Returns if the labels should be visible. - * - * @return the visibility flag for the labels - */ - public boolean isShowLabels() { - return mShowLabels; - } - - /** - * Sets if the labels should be visible. - * - * @param showLabels the visibility flag for the labels - */ - public void setShowLabels(boolean showLabels) { - mShowLabels = showLabels; - } - - /** - * Returns if the X axis grid should be visible. - * - * @return the visibility flag for the X axis grid - */ - public boolean isShowGridX() { - return mShowGridX; - } - - /** - * Returns if the Y axis grid should be visible. - * - * @return the visibility flag for the Y axis grid - */ - public boolean isShowGridY() { - return mShowGridY; - } - - /** - * Sets if the X axis grid should be visible. - * - * @param showGrid the visibility flag for the X axis grid - */ - public void setShowGridX(boolean showGrid) { - mShowGridX = showGrid; - } - - /** - * Sets if the Y axis grid should be visible. - * - * @param showGrid the visibility flag for the Y axis grid - */ - public void setShowGridY(boolean showGrid) { - mShowGridY = showGrid; - } - - /** - * Sets if the grid should be visible. - * - * @param showGrid the visibility flag for the grid - */ - public void setShowGrid(boolean showGrid) { - setShowGridX(showGrid); - setShowGridY(showGrid); - } - - /** - * Returns if the grid should be visible for custom X or Y labels. - * - * @return the visibility flag for the custom text grid - */ - public boolean isShowCustomTextGrid() { - return mShowCustomTextGrid; - } - - /** - * Sets if the grid for custom X or Y labels should be visible. - * - * @param showGrid the visibility flag for the custom text grid - */ - public void setShowCustomTextGrid(boolean showGrid) { - mShowCustomTextGrid = showGrid; - } - - /** - * Returns if the legend should be visible. - * - * @return the visibility flag for the legend - */ - public boolean isShowLegend() { - return mShowLegend; - } - - /** - * Sets if the legend should be visible. - * - * @param showLegend the visibility flag for the legend - */ - public void setShowLegend(boolean showLegend) { - mShowLegend = showLegend; - } - - /** - * Returns if the legend should size to fit. - * - * @return the fit behavior - */ - public boolean isFitLegend() { - return mFitLegend; - } - - /** - * Sets if the legend should size to fit. - * - * @param fit the fit behavior - */ - public void setFitLegend(boolean fit) { - mFitLegend = fit; - } - - /** - * Returns the text typeface name. - * - * @return the text typeface name - */ - public String getTextTypefaceName() { - return mTextTypefaceName; - } - - /** - * Returns the text typeface style. - * - * @return the text typeface style - */ - public int getTextTypefaceStyle() { - return mTextTypefaceStyle; - } - - /** - * Returns the legend text size. - * - * @return the legend text size - */ - public float getLegendTextSize() { - return mLegendTextSize; - } - - /** - * Sets the legend text size. - * - * @param textSize the legend text size - */ - public void setLegendTextSize(float textSize) { - mLegendTextSize = textSize; - } - - /** - * Sets the text typeface name and style. - * - * @param typefaceName the text typeface name - * @param style the text typeface style - */ - public void setTextTypeface(String typefaceName, int style) { - mTextTypefaceName = typefaceName; - mTextTypefaceStyle = style; - } - - /** - * Returns the antialiasing flag value. - * - * @return the antialiasing value - */ - public boolean isAntialiasing() { - return mAntialiasing; - } - - /** - * Sets the antialiasing value. - * - * @param antialiasing the antialiasing - */ - public void setAntialiasing(boolean antialiasing) { - mAntialiasing = antialiasing; - } - - /** - * Returns the value to be used for scaling the chart. - * - * @return the scale value - */ - public float getScale() { - return mScale; - } - - /** - * Returns the original value to be used for scaling the chart. - * - * @return the original scale value - */ - public float getOriginalScale() { - return mOriginalScale; - } - - /** - * Sets the value to be used for scaling the chart. It works on some charts - * like pie, doughnut, dial. - * - * @param scale the scale value - */ - public void setScale(float scale) { - mScale = scale; - } - - /** - * Returns the enabled state of the zoom. - * - * @return if zoom is enabled - */ - public boolean isZoomEnabled() { - return mZoomEnabled; - } - - /** - * Sets the enabled state of the zoom. - * - * @param enabled zoom enabled - */ - public void setZoomEnabled(boolean enabled) { - mZoomEnabled = enabled; - } - - /** - * Returns the visible state of the zoom buttons. - * - * @return if zoom buttons are visible - */ - public boolean isZoomButtonsVisible() { - return mZoomButtonsVisible; - } - - /** - * Sets the visible state of the zoom buttons. - * - * @param visible if the zoom buttons are visible - */ - public void setZoomButtonsVisible(boolean visible) { - mZoomButtonsVisible = visible; - } - - /** - * Returns the enabled state of the external (application implemented) zoom. - * - * @return if external zoom is enabled - */ - public boolean isExternalZoomEnabled() { - return mExternalZoomEnabled; - } - - /** - * Sets the enabled state of the external (application implemented) zoom. - * - * @param enabled external zoom enabled - */ - public void setExternalZoomEnabled(boolean enabled) { - mExternalZoomEnabled = enabled; - } - - /** - * Returns the zoom rate. - * - * @return the zoom rate - */ - public float getZoomRate() { - return mZoomRate; - } - - /** - * Returns the enabled state of the pan. - * - * @return if pan is enabled - */ - public boolean isPanEnabled() { - return mPanEnabled; - } - - /** - * Sets the enabled state of the pan. - * - * @param enabled pan enabled - */ - public void setPanEnabled(boolean enabled) { - mPanEnabled = enabled; - } - - /** - * Sets the zoom rate. - * - * @param rate the zoom rate - */ - public void setZoomRate(float rate) { - mZoomRate = rate; - } - - /** - * Returns the enabled state of the click. - * - * @return if click is enabled - */ - public boolean isClickEnabled() { - return mClickEnabled; - } - - /** - * Sets the enabled state of the click. - * - * @param enabled click enabled - */ - public void setClickEnabled(boolean enabled) { - mClickEnabled = enabled; - } - - /** - * Returns the selectable radius value around clickable points. - * - * @return the selectable radius - */ - public int getSelectableBuffer() { - return selectableBuffer; - } - - /** - * Sets the selectable radius value around clickable points. - * - * @param buffer the selectable radius - */ - public void setSelectableBuffer(int buffer) { - selectableBuffer = buffer; - } - - /** - * Returns the legend height. - * - * @return the legend height - */ - public int getLegendHeight() { - return mLegendHeight; - } - - /** - * Sets the legend height, in pixels. - * - * @param height the legend height - */ - public void setLegendHeight(int height) { - mLegendHeight = height; - } - - /** - * Returns the margin sizes. An array containing the margins in this order: - * top, left, bottom, right - * - * @return the margin sizes - */ - public int[] getMargins() { - return mMargins; - } - - /** - * Sets the margins, in pixels. - * - * @param margins an array containing the margin size values, in this order: - * top, left, bottom, right - */ - public void setMargins(int[] margins) { - mMargins = margins; - } - - /** - * Returns if the chart is inside a scroll view and doesn't need to shrink. - * - * @return if it is inside a scroll view - */ - public boolean isInScroll() { - return mInScroll; - } - - /** - * To be set if the chart is inside a scroll view and doesn't need to shrink - * when not enough space. - * - * @param inScroll if it is inside a scroll view - */ - public void setInScroll(boolean inScroll) { - mInScroll = inScroll; - } - - /** - * Returns the start angle for circular charts such as pie, doughnut. An angle - * of 0 degrees correspond to the geometric angle of 0 degrees (3 o'clock on a - * watch.) - * - * @return the start angle in degrees - */ - public float getStartAngle() { - return mStartAngle; - } - - /** - * Sets the start angle for circular charts such as pie, doughnut, etc. An - * angle of 0 degrees correspond to the geometric angle of 0 degrees (3 - * o'clock on a watch.) - * - * @param startAngle the start angle in degrees - */ - public void setStartAngle(float startAngle) { - mStartAngle = startAngle; - } - - /** - * Returns if the values should be displayed as text. - * - * @return if the values should be displayed as text - */ - public boolean isDisplayValues() { - return mDisplayValues; - } - - /** - * Sets if the values should be displayed as text (supported by pie chart). - * - * @param display if the values should be displayed as text - */ - public void setDisplayValues(boolean display) { - mDisplayValues = display; - } - -} diff --git a/android-libraries/achartengine/src/org/achartengine/renderer/DialRenderer.java b/android-libraries/achartengine/src/org/achartengine/renderer/DialRenderer.java deleted file mode 100644 index 1ed84619d..000000000 --- a/android-libraries/achartengine/src/org/achartengine/renderer/DialRenderer.java +++ /dev/null @@ -1,196 +0,0 @@ -/** - * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.achartengine.renderer; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import org.achartengine.util.MathHelper; - -/** - * Dial chart renderer. - */ -public class DialRenderer extends DefaultRenderer { - /** The start angle in the dial range. */ - private double mAngleMin = 330; - /** The end angle in the dial range. */ - private double mAngleMax = 30; - /** The start value in dial range. */ - private double mMinValue = MathHelper.NULL_VALUE; - /** The end value in dial range. */ - private double mMaxValue = -MathHelper.NULL_VALUE; - /** The spacing for the minor ticks. */ - private double mMinorTickSpacing = MathHelper.NULL_VALUE; - /** The spacing for the major ticks. */ - private double mMajorTickSpacing = MathHelper.NULL_VALUE; - /** An array of the renderers types (default is NEEDLE). */ - private List mVisualTypes = new ArrayList(); - - public enum Type { - NEEDLE, ARROW; - } - - /** - * Returns the start angle value of the dial. - * - * @return the angle start value - */ - public double getAngleMin() { - return mAngleMin; - } - - /** - * Sets the start angle value of the dial. - * - * @param min the dial angle start value - */ - public void setAngleMin(double min) { - mAngleMin = min; - } - - /** - * Returns the end angle value of the dial. - * - * @return the angle end value - */ - public double getAngleMax() { - return mAngleMax; - } - - /** - * Sets the end angle value of the dial. - * - * @param max the dial angle end value - */ - public void setAngleMax(double max) { - mAngleMax = max; - } - - /** - * Returns the start value to be rendered on the dial. - * - * @return the start value on dial - */ - public double getMinValue() { - return mMinValue; - } - - /** - * Sets the start value to be rendered on the dial. - * - * @param min the start value on the dial - */ - public void setMinValue(double min) { - mMinValue = min; - } - - /** - * Returns if the minimum dial value was set. - * - * @return the minimum dial value was set or not - */ - public boolean isMinValueSet() { - return mMinValue != MathHelper.NULL_VALUE; - } - - /** - * Returns the end value to be rendered on the dial. - * - * @return the end value on the dial - */ - public double getMaxValue() { - return mMaxValue; - } - - /** - * Sets the end value to be rendered on the dial. - * - * @param max the end value on the dial - */ - public void setMaxValue(double max) { - mMaxValue = max; - } - - /** - * Returns if the maximum dial value was set. - * - * @return the maximum dial was set or not - */ - public boolean isMaxValueSet() { - return mMaxValue != -MathHelper.NULL_VALUE; - } - - /** - * Returns the minor ticks spacing. - * - * @return the minor ticks spacing - */ - public double getMinorTicksSpacing() { - return mMinorTickSpacing; - } - - /** - * Sets the minor ticks spacing. - * - * @param spacing the minor ticks spacing - */ - public void setMinorTicksSpacing(double spacing) { - mMinorTickSpacing = spacing; - } - - /** - * Returns the major ticks spacing. - * - * @return the major ticks spacing - */ - public double getMajorTicksSpacing() { - return mMajorTickSpacing; - } - - /** - * Sets the major ticks spacing. - * - * @param spacing the major ticks spacing - */ - public void setMajorTicksSpacing(double spacing) { - mMajorTickSpacing = spacing; - } - - /** - * Returns the visual type at the specified index. - * - * @param index the index - * @return the visual type - */ - public Type getVisualTypeForIndex(int index) { - if (index < mVisualTypes.size()) { - return mVisualTypes.get(index); - } - return Type.NEEDLE; - } - - /** - * Sets the visual types. - * - * @param types the visual types - */ - public void setVisualTypes(Type[] types) { - mVisualTypes.clear(); - mVisualTypes.addAll(Arrays.asList(types)); - } - -} diff --git a/android-libraries/achartengine/src/org/achartengine/renderer/SimpleSeriesRenderer.java b/android-libraries/achartengine/src/org/achartengine/renderer/SimpleSeriesRenderer.java deleted file mode 100644 index 0763fc58e..000000000 --- a/android-libraries/achartengine/src/org/achartengine/renderer/SimpleSeriesRenderer.java +++ /dev/null @@ -1,235 +0,0 @@ -/** - * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.achartengine.renderer; - -import java.io.Serializable; - -import android.graphics.Color; -import android.graphics.Paint.Align; - -/** - * A simple series renderer. - */ -public class SimpleSeriesRenderer implements Serializable { - /** The series color. */ - private int mColor = Color.BLUE; - /** If the values should be displayed above the chart points. */ - private boolean mDisplayChartValues; - /** The chart values text size. */ - private float mChartValuesTextSize = 10; - /** The chart values text alignment. */ - private Align mChartValuesTextAlign = Align.CENTER; - /** The chart values spacing from the data point. */ - private float mChartValuesSpacing = 5f; - /** The stroke style. */ - private BasicStroke mStroke; - /** If gradient is enabled. */ - private boolean mGradientEnabled = false; - /** The gradient start value. */ - private double mGradientStartValue; - /** The gradient start color. */ - private int mGradientStartColor; - /** The gradient stop value. */ - private double mGradientStopValue; - /** The gradient stop color. */ - private int mGradientStopColor; - - /** - * Returns the series color. - * - * @return the series color - */ - public int getColor() { - return mColor; - } - - /** - * Sets the series color. - * - * @param color the series color - */ - public void setColor(int color) { - mColor = color; - } - - /** - * Returns if the chart point values should be displayed as text. - * - * @return if the chart point values should be displayed as text - */ - public boolean isDisplayChartValues() { - return mDisplayChartValues; - } - - /** - * Sets if the chart point values should be displayed as text. - * - * @param display if the chart point values should be displayed as text - */ - public void setDisplayChartValues(boolean display) { - mDisplayChartValues = display; - } - - /** - * Returns the chart values text size. - * - * @return the chart values text size - */ - public float getChartValuesTextSize() { - return mChartValuesTextSize; - } - - /** - * Sets the chart values text size. - * - * @param textSize the chart values text size - */ - public void setChartValuesTextSize(float textSize) { - mChartValuesTextSize = textSize; - } - - /** - * Returns the chart values text align. - * - * @return the chart values text align - */ - public Align getChartValuesTextAlign() { - return mChartValuesTextAlign; - } - - /** - * Sets the chart values text align. - * - * @param align the chart values text align - */ - public void setChartValuesTextAlign(Align align) { - mChartValuesTextAlign = align; - } - - /** - * Returns the chart values spacing from the data point. - * - * @return the chart values spacing - */ - public float getChartValuesSpacing() { - return mChartValuesSpacing; - } - - /** - * Sets the chart values spacing from the data point. - * - * @param spacing the chart values spacing (in pixels) from the chart data - * point - */ - public void setChartValuesSpacing(float spacing) { - mChartValuesSpacing = spacing; - } - - /** - * Returns the stroke style. - * - * @return the stroke style - */ - public BasicStroke getStroke() { - return mStroke; - } - - /** - * Sets the stroke style. - * - * @param stroke the stroke style - */ - public void setStroke(BasicStroke stroke) { - mStroke = stroke; - } - - /** - * Returns the gradient is enabled value. - * - * @return the gradient enabled - */ - public boolean isGradientEnabled() { - return mGradientEnabled; - } - - /** - * Sets the gradient enabled value. - * - * @param enabled the gradient enabled - */ - public void setGradientEnabled(boolean enabled) { - mGradientEnabled = enabled; - } - - /** - * Returns the gradient start value. - * - * @return the gradient start value - */ - public double getGradientStartValue() { - return mGradientStartValue; - } - - /** - * Returns the gradient start color. - * - * @return the gradient start color - */ - public int getGradientStartColor() { - return mGradientStartColor; - } - - /** - * Sets the gradient start value and color. - * - * @param start the gradient start value - * @param color the gradient start color - */ - public void setGradientStart(double start, int color) { - mGradientStartValue = start; - mGradientStartColor = color; - } - - /** - * Returns the gradient stop value. - * - * @return the gradient stop value - */ - public double getGradientStopValue() { - return mGradientStopValue; - } - - /** - * Returns the gradient stop color. - * - * @return the gradient stop color - */ - public int getGradientStopColor() { - return mGradientStopColor; - } - - /** - * Sets the gradient stop value and color. - * - * @param start the gradient stop value - * @param color the gradient stop color - */ - public void setGradientStop(double start, int color) { - mGradientStopValue = start; - mGradientStopColor = color; - } - -} diff --git a/android-libraries/achartengine/src/org/achartengine/renderer/XYMultipleSeriesRenderer.java b/android-libraries/achartengine/src/org/achartengine/renderer/XYMultipleSeriesRenderer.java deleted file mode 100644 index 64b342117..000000000 --- a/android-libraries/achartengine/src/org/achartengine/renderer/XYMultipleSeriesRenderer.java +++ /dev/null @@ -1,1101 +0,0 @@ -/** - * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.achartengine.renderer; - -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.Map; - -import org.achartengine.util.MathHelper; - -import android.graphics.Color; -import android.graphics.Paint.Align; - -/** - * Multiple XY series renderer. - */ -public class XYMultipleSeriesRenderer extends DefaultRenderer { - /** The X axis title. */ - private String mXTitle = ""; - /** The Y axis title. */ - private String[] mYTitle; - /** The axis title text size. */ - private float mAxisTitleTextSize = 12; - /** The start value in the X axis range. */ - private double[] mMinX; - /** The end value in the X axis range. */ - private double[] mMaxX; - /** The start value in the Y axis range. */ - private double[] mMinY; - /** The end value in the Y axis range. */ - private double[] mMaxY; - /** The approximative number of labels on the x axis. */ - private int mXLabels = 5; - /** The approximative number of labels on the y axis. */ - private int mYLabels = 5; - /** The current orientation of the chart. */ - private Orientation mOrientation = Orientation.HORIZONTAL; - /** The X axis text labels. */ - private Map mXTextLabels = new HashMap(); - /** The Y axis text labels. */ - private Map> mYTextLabels = new LinkedHashMap>(); - /** A flag for enabling or not the pan on the X axis. */ - private boolean mPanXEnabled = true; - /** A flag for enabling or not the pan on the Y axis. */ - private boolean mPanYEnabled = true; - /** A flag for enabling or not the zoom on the X axis. */ - private boolean mZoomXEnabled = true; - /** A flag for enabling or not the zoom on the Y axis . */ - private boolean mZoomYEnabled = true; - /** The spacing between bars, in bar charts. */ - private double mBarSpacing = 0; - /** The margins colors. */ - private int mMarginsColor = NO_COLOR; - /** The pan limits. */ - private double[] mPanLimits; - /** The zoom limits. */ - private double[] mZoomLimits; - /** The X axis labels rotation angle. */ - private float mXLabelsAngle; - /** The Y axis labels rotation angle. */ - private float mYLabelsAngle; - /** The initial axis range. */ - private Map initialRange = new LinkedHashMap(); - /** The point size for charts displaying points. */ - private float mPointSize = 3; - /** The grid color. */ - private int mGridColor = Color.argb(75, 200, 200, 200); - /** The number of scales. */ - private int scalesCount; - /** The X axis labels alignment. */ - private Align xLabelsAlign = Align.CENTER; - /** The Y axis labels alignment. */ - private Align[] yLabelsAlign; - /** The Y axis alignment. */ - private Align[] yAxisAlign; - /** The X axis labels color. */ - private int mXLabelsColor = TEXT_COLOR; - /** The Y axis labels color. */ - private int[] mYLabelsColor = new int[] { TEXT_COLOR }; - /** - * If X axis value selection algorithm to be used. Only used by the time - * charts. - */ - private boolean mXRoundedLabels = true; - - /** - * An enum for the XY chart orientation of the X axis. - */ - public enum Orientation { - HORIZONTAL(0), VERTICAL(90); - /** The rotate angle. */ - private int mAngle = 0; - - private Orientation(int angle) { - mAngle = angle; - } - - /** - * Return the orientation rotate angle. - * - * @return the orientaion rotate angle - */ - public int getAngle() { - return mAngle; - } - } - - public XYMultipleSeriesRenderer() { - this(1); - } - - public XYMultipleSeriesRenderer(int scaleNumber) { - scalesCount = scaleNumber; - initAxesRange(scaleNumber); - } - - public void initAxesRange(int scales) { - mYTitle = new String[scales]; - yLabelsAlign = new Align[scales]; - yAxisAlign = new Align[scales]; - mYLabelsColor = new int[scales]; - mMinX = new double[scales]; - mMaxX = new double[scales]; - mMinY = new double[scales]; - mMaxY = new double[scales]; - for (int i = 0; i < scales; i++) { - mYLabelsColor[i] = TEXT_COLOR; - initAxesRangeForScale(i); - } - } - - public void initAxesRangeForScale(int i) { - mMinX[i] = MathHelper.NULL_VALUE; - mMaxX[i] = -MathHelper.NULL_VALUE; - mMinY[i] = MathHelper.NULL_VALUE; - mMaxY[i] = -MathHelper.NULL_VALUE; - double[] range = new double[] { mMinX[i], mMaxX[i], mMinY[i], mMaxY[i] }; - initialRange.put(i, range); - mYTitle[i] = ""; - mYTextLabels.put(i, new HashMap()); - yLabelsAlign[i] = Align.CENTER; - yAxisAlign[i] = Align.LEFT; - } - - /** - * Returns the current orientation of the chart X axis. - * - * @return the chart orientation - */ - public Orientation getOrientation() { - return mOrientation; - } - - /** - * Sets the current orientation of the chart X axis. - * - * @param orientation the chart orientation - */ - public void setOrientation(Orientation orientation) { - mOrientation = orientation; - } - - /** - * Returns the title for the X axis. - * - * @return the X axis title - */ - public String getXTitle() { - return mXTitle; - } - - /** - * Sets the title for the X axis. - * - * @param title the X axis title - */ - public void setXTitle(String title) { - mXTitle = title; - } - - /** - * Returns the title for the Y axis. - * - * @return the Y axis title - */ - public String getYTitle() { - return getYTitle(0); - } - - /** - * Returns the title for the Y axis. - * - * @param scale the renderer scale - * @return the Y axis title - */ - public String getYTitle(int scale) { - return mYTitle[scale]; - } - - /** - * Sets the title for the Y axis. - * - * @param title the Y axis title - */ - public void setYTitle(String title) { - setYTitle(title, 0); - } - - /** - * Sets the title for the Y axis. - * - * @param title the Y axis title - * @param scale the renderer scale - */ - public void setYTitle(String title, int scale) { - mYTitle[scale] = title; - } - - /** - * Returns the axis title text size. - * - * @return the axis title text size - */ - public float getAxisTitleTextSize() { - return mAxisTitleTextSize; - } - - /** - * Sets the axis title text size. - * - * @param textSize the chart axis text size - */ - public void setAxisTitleTextSize(float textSize) { - mAxisTitleTextSize = textSize; - } - - /** - * Returns the start value of the X axis range. - * - * @return the X axis range start value - */ - public double getXAxisMin() { - return getXAxisMin(0); - } - - /** - * Sets the start value of the X axis range. - * - * @param min the X axis range start value - */ - public void setXAxisMin(double min) { - setXAxisMin(min, 0); - } - - /** - * Returns if the minimum X value was set. - * - * @return the minX was set or not - */ - public boolean isMinXSet() { - return isMinXSet(0); - } - - /** - * Returns the end value of the X axis range. - * - * @return the X axis range end value - */ - public double getXAxisMax() { - return getXAxisMax(0); - } - - /** - * Sets the end value of the X axis range. - * - * @param max the X axis range end value - */ - public void setXAxisMax(double max) { - setXAxisMax(max, 0); - } - - /** - * Returns if the maximum X value was set. - * - * @return the maxX was set or not - */ - public boolean isMaxXSet() { - return isMaxXSet(0); - } - - /** - * Returns the start value of the Y axis range. - * - * @return the Y axis range end value - */ - public double getYAxisMin() { - return getYAxisMin(0); - } - - /** - * Sets the start value of the Y axis range. - * - * @param min the Y axis range start value - */ - public void setYAxisMin(double min) { - setYAxisMin(min, 0); - } - - /** - * Returns if the minimum Y value was set. - * - * @return the minY was set or not - */ - public boolean isMinYSet() { - return isMinYSet(0); - } - - /** - * Returns the end value of the Y axis range. - * - * @return the Y axis range end value - */ - public double getYAxisMax() { - return getYAxisMax(0); - } - - /** - * Sets the end value of the Y axis range. - * - * @param max the Y axis range end value - */ - public void setYAxisMax(double max) { - setYAxisMax(max, 0); - } - - /** - * Returns if the maximum Y value was set. - * - * @return the maxY was set or not - */ - public boolean isMaxYSet() { - return isMaxYSet(0); - } - - /** - * Returns the start value of the X axis range. - * - * @param scale the renderer scale - * @return the X axis range start value - */ - public double getXAxisMin(int scale) { - return mMinX[scale]; - } - - /** - * Sets the start value of the X axis range. - * - * @param min the X axis range start value - * @param scale the renderer scale - */ - public void setXAxisMin(double min, int scale) { - if (!isMinXSet(scale)) { - initialRange.get(scale)[0] = min; - } - mMinX[scale] = min; - } - - /** - * Returns if the minimum X value was set. - * - * @param scale the renderer scale - * @return the minX was set or not - */ - public boolean isMinXSet(int scale) { - return mMinX[scale] != MathHelper.NULL_VALUE; - } - - /** - * Returns the end value of the X axis range. - * - * @param scale the renderer scale - * @return the X axis range end value - */ - public double getXAxisMax(int scale) { - return mMaxX[scale]; - } - - /** - * Sets the end value of the X axis range. - * - * @param max the X axis range end value - * @param scale the renderer scale - */ - public void setXAxisMax(double max, int scale) { - if (!isMaxXSet(scale)) { - initialRange.get(scale)[1] = max; - } - mMaxX[scale] = max; - } - - /** - * Returns if the maximum X value was set. - * - * @param scale the renderer scale - * @return the maxX was set or not - */ - public boolean isMaxXSet(int scale) { - return mMaxX[scale] != -MathHelper.NULL_VALUE; - } - - /** - * Returns the start value of the Y axis range. - * - * @param scale the renderer scale - * @return the Y axis range end value - */ - public double getYAxisMin(int scale) { - return mMinY[scale]; - } - - /** - * Sets the start value of the Y axis range. - * - * @param min the Y axis range start value - * @param scale the renderer scale - */ - public void setYAxisMin(double min, int scale) { - if (!isMinYSet(scale)) { - initialRange.get(scale)[2] = min; - } - mMinY[scale] = min; - } - - /** - * Returns if the minimum Y value was set. - * - * @param scale the renderer scale - * @return the minY was set or not - */ - public boolean isMinYSet(int scale) { - return mMinY[scale] != MathHelper.NULL_VALUE; - } - - /** - * Returns the end value of the Y axis range. - * - * @param scale the renderer scale - * @return the Y axis range end value - */ - public double getYAxisMax(int scale) { - return mMaxY[scale]; - } - - /** - * Sets the end value of the Y axis range. - * - * @param max the Y axis range end value - * @param scale the renderer scale - */ - public void setYAxisMax(double max, int scale) { - if (!isMaxYSet(scale)) { - initialRange.get(scale)[3] = max; - } - mMaxY[scale] = max; - } - - /** - * Returns if the maximum Y value was set. - * - * @param scale the renderer scale - * @return the maxY was set or not - */ - public boolean isMaxYSet(int scale) { - return mMaxY[scale] != -MathHelper.NULL_VALUE; - } - - /** - * Returns the approximate number of labels for the X axis. - * - * @return the approximate number of labels for the X axis - */ - public int getXLabels() { - return mXLabels; - } - - /** - * Sets the approximate number of labels for the X axis. - * - * @param xLabels the approximate number of labels for the X axis - */ - public void setXLabels(int xLabels) { - mXLabels = xLabels; - } - - /** - * Adds a new text label for the specified X axis value. - * - * @param x the X axis value - * @param text the text label - * @deprecated use addXTextLabel instead - */ - public void addTextLabel(double x, String text) { - addXTextLabel(x, text); - } - - /** - * Adds a new text label for the specified X axis value. - * - * @param x the X axis value - * @param text the text label - */ - public void addXTextLabel(double x, String text) { - mXTextLabels.put(x, text); - } - - /** - * Returns the X axis text label at the specified X axis value. - * - * @param x the X axis value - * @return the X axis text label - */ - public String getXTextLabel(Double x) { - return mXTextLabels.get(x); - } - - /** - * Returns the X text label locations. - * - * @return the X text label locations - */ - public Double[] getXTextLabelLocations() { - return mXTextLabels.keySet().toArray(new Double[0]); - } - - /** - * Clears the existing text labels. - * - * @deprecated use clearXTextLabels instead - */ - public void clearTextLabels() { - clearXTextLabels(); - } - - /** - * Clears the existing text labels on the X axis. - */ - public void clearXTextLabels() { - mXTextLabels.clear(); - } - - /** - * If X axis labels should be rounded. - * - * @return if rounded time values to be used - */ - public boolean isXRoundedLabels() { - return mXRoundedLabels; - } - - /** - * Sets if X axis rounded time values to be used. - * - * @param rounded rounded values to be used - */ - public void setXRoundedLabels(boolean rounded) { - mXRoundedLabels = rounded; - } - - /** - * Adds a new text label for the specified Y axis value. - * - * @param y the Y axis value - * @param text the text label - */ - public void addYTextLabel(double y, String text) { - addYTextLabel(y, text, 0); - } - - /** - * Adds a new text label for the specified Y axis value. - * - * @param y the Y axis value - * @param text the text label - * @param scale the renderer scale - */ - public void addYTextLabel(double y, String text, int scale) { - mYTextLabels.get(scale).put(y, text); - } - - /** - * Returns the Y axis text label at the specified Y axis value. - * - * @param y the Y axis value - * @return the Y axis text label - */ - public String getYTextLabel(Double y) { - return getYTextLabel(y, 0); - } - - /** - * Returns the Y axis text label at the specified Y axis value. - * - * @param y the Y axis value - * @param scale the renderer scale - * @return the Y axis text label - */ - public String getYTextLabel(Double y, int scale) { - return mYTextLabels.get(scale).get(y); - } - - /** - * Returns the Y text label locations. - * - * @return the Y text label locations - */ - public Double[] getYTextLabelLocations() { - return getYTextLabelLocations(0); - } - - /** - * Returns the Y text label locations. - * - * @param scale the renderer scale - * @return the Y text label locations - */ - public Double[] getYTextLabelLocations(int scale) { - return mYTextLabels.get(scale).keySet().toArray(new Double[0]); - } - - /** - * Clears the existing text labels on the Y axis. - */ - public void clearYTextLabels() { - clearYTextLabels(0); - } - - /** - * Clears the existing text labels on the Y axis. - * - * @param scale the renderer scale - */ - public void clearYTextLabels(int scale) { - mYTextLabels.get(scale).clear(); - } - - /** - * Returns the approximate number of labels for the Y axis. - * - * @return the approximate number of labels for the Y axis - */ - public int getYLabels() { - return mYLabels; - } - - /** - * Sets the approximate number of labels for the Y axis. - * - * @param yLabels the approximate number of labels for the Y axis - */ - public void setYLabels(int yLabels) { - mYLabels = yLabels; - } - - /** - * Sets if the chart point values should be displayed as text. - * - * @param display if the chart point values should be displayed as text - * @deprecated use SimpleSeriesRenderer.setDisplayChartValues() instead - */ - public void setDisplayChartValues(boolean display) { - SimpleSeriesRenderer[] renderers = getSeriesRenderers(); - for (SimpleSeriesRenderer renderer : renderers) { - renderer.setDisplayChartValues(display); - } - } - - /** - * Sets the chart values text size. - * - * @param textSize the chart values text size - * @deprecated use SimpleSeriesRenderer.setChartValuesTextSize() instead - */ - public void setChartValuesTextSize(float textSize) { - SimpleSeriesRenderer[] renderers = getSeriesRenderers(); - for (SimpleSeriesRenderer renderer : renderers) { - renderer.setChartValuesTextSize(textSize); - } - } - - /** - * Returns the enabled state of the pan on at least one axis. - * - * @return if pan is enabled - */ - public boolean isPanEnabled() { - return isPanXEnabled() || isPanYEnabled(); - } - - /** - * Returns the enabled state of the pan on X axis. - * - * @return if pan is enabled on X axis - */ - public boolean isPanXEnabled() { - return mPanXEnabled; - } - - /** - * Returns the enabled state of the pan on Y axis. - * - * @return if pan is enabled on Y axis - */ - public boolean isPanYEnabled() { - return mPanYEnabled; - } - - /** - * Sets the enabled state of the pan. - * - * @param enabledX pan enabled on X axis - * @param enabledY pan enabled on Y axis - */ - public void setPanEnabled(boolean enabledX, boolean enabledY) { - mPanXEnabled = enabledX; - mPanYEnabled = enabledY; - } - - /** - * Returns the enabled state of the zoom on at least one axis. - * - * @return if zoom is enabled - */ - public boolean isZoomEnabled() { - return isZoomXEnabled() || isZoomYEnabled(); - } - - /** - * Returns the enabled state of the zoom on X axis. - * - * @return if zoom is enabled on X axis - */ - public boolean isZoomXEnabled() { - return mZoomXEnabled; - } - - /** - * Returns the enabled state of the zoom on Y axis. - * - * @return if zoom is enabled on Y axis - */ - public boolean isZoomYEnabled() { - return mZoomYEnabled; - } - - /** - * Sets the enabled state of the zoom. - * - * @param enabledX zoom enabled on X axis - * @param enabledY zoom enabled on Y axis - */ - public void setZoomEnabled(boolean enabledX, boolean enabledY) { - mZoomXEnabled = enabledX; - mZoomYEnabled = enabledY; - } - - /** - * Returns the spacing between bars, in bar charts. - * - * @return the spacing between bars - * @deprecated use getBarSpacing instead - */ - public double getBarsSpacing() { - return getBarSpacing(); - } - - /** - * Returns the spacing between bars, in bar charts. - * - * @return the spacing between bars - */ - public double getBarSpacing() { - return mBarSpacing; - } - - /** - * Sets the spacing between bars, in bar charts. Only available for bar - * charts. This is a coefficient of the bar width. For instance, if you want - * the spacing to be a half of the bar width, set this value to 0.5. - * - * @param spacing the spacing between bars coefficient - */ - public void setBarSpacing(double spacing) { - mBarSpacing = spacing; - } - - /** - * Returns the margins color. - * - * @return the margins color - */ - public int getMarginsColor() { - return mMarginsColor; - } - - /** - * Sets the color of the margins. - * - * @param color the margins color - */ - public void setMarginsColor(int color) { - mMarginsColor = color; - } - - /** - * Returns the grid color. - * - * @return the grid color - */ - public int getGridColor() { - return mGridColor; - } - - /** - * Sets the color of the grid. - * - * @param color the grid color - */ - public void setGridColor(int color) { - mGridColor = color; - } - - /** - * Returns the pan limits. - * - * @return the pan limits - */ - public double[] getPanLimits() { - return mPanLimits; - } - - /** - * Sets the pan limits as an array of 4 values. Setting it to null or a - * different size array will disable the panning limitation. Values: - * [panMinimumX, panMaximumX, panMinimumY, panMaximumY] - * - * @param panLimits the pan limits - */ - public void setPanLimits(double[] panLimits) { - mPanLimits = panLimits; - } - - /** - * Returns the zoom limits. - * - * @return the zoom limits - */ - public double[] getZoomLimits() { - return mZoomLimits; - } - - /** - * Sets the zoom limits as an array of 4 values. Setting it to null or a - * different size array will disable the zooming limitation. Values: - * [zoomMinimumX, zoomMaximumX, zoomMinimumY, zoomMaximumY] - * - * @param zoomLimits the zoom limits - */ - public void setZoomLimits(double[] zoomLimits) { - mZoomLimits = zoomLimits; - } - - /** - * Returns the rotation angle of labels for the X axis. - * - * @return the rotation angle of labels for the X axis - */ - public float getXLabelsAngle() { - return mXLabelsAngle; - } - - /** - * Sets the rotation angle (in degrees) of labels for the X axis. - * - * @param angle the rotation angle of labels for the X axis - */ - public void setXLabelsAngle(float angle) { - mXLabelsAngle = angle; - } - - /** - * Returns the rotation angle of labels for the Y axis. - * - * @return the approximate number of labels for the Y axis - */ - public float getYLabelsAngle() { - return mYLabelsAngle; - } - - /** - * Sets the rotation angle (in degrees) of labels for the Y axis. - * - * @param angle the rotation angle of labels for the Y axis - */ - public void setYLabelsAngle(float angle) { - mYLabelsAngle = angle; - } - - /** - * Returns the size of the points, for charts displaying points. - * - * @return the point size - */ - public float getPointSize() { - return mPointSize; - } - - /** - * Sets the size of the points, for charts displaying points. - * - * @param size the point size - */ - public void setPointSize(float size) { - mPointSize = size; - } - - public void setRange(double[] range) { - setRange(range, 0); - } - - /** - * Sets the axes range values. - * - * @param range an array having the values in this order: minX, maxX, minY, - * maxY - * @param scale the renderer scale - */ - public void setRange(double[] range, int scale) { - setXAxisMin(range[0], scale); - setXAxisMax(range[1], scale); - setYAxisMin(range[2], scale); - setYAxisMax(range[3], scale); - } - - public boolean isInitialRangeSet() { - return isInitialRangeSet(0); - } - - /** - * Returns if the initial range is set. - * - * @param scale the renderer scale - * @return the initial range was set or not - */ - public boolean isInitialRangeSet(int scale) { - return initialRange.get(scale) != null; - } - - /** - * Returns the initial range. - * - * @return the initial range - */ - public double[] getInitialRange() { - return getInitialRange(0); - } - - /** - * Returns the initial range. - * - * @param scale the renderer scale - * @return the initial range - */ - public double[] getInitialRange(int scale) { - return initialRange.get(scale); - } - - /** - * Sets the axes initial range values. This will be used in the zoom fit tool. - * - * @param range an array having the values in this order: minX, maxX, minY, - * maxY - */ - public void setInitialRange(double[] range) { - setInitialRange(range, 0); - } - - /** - * Sets the axes initial range values. This will be used in the zoom fit tool. - * - * @param range an array having the values in this order: minX, maxX, minY, - * maxY - * @param scale the renderer scale - */ - public void setInitialRange(double[] range, int scale) { - initialRange.put(scale, range); - } - - /** - * Returns the X axis labels color. - * - * @return the X axis labels color - */ - public int getXLabelsColor() { - return mXLabelsColor; - } - - /** - * Returns the Y axis labels color. - * - * @return the Y axis labels color - */ - public int getYLabelsColor(int scale) { - return mYLabelsColor[scale]; - } - - /** - * Sets the X axis labels color. - * - * @param color the X axis labels color - */ - public void setXLabelsColor(int color) { - mXLabelsColor = color; - } - - /** - * Sets the Y axis labels color. - * - * @param scale the renderer scale - * @param color the Y axis labels color - */ - public void setYLabelsColor(int scale, int color) { - mYLabelsColor[scale] = color; - } - - /** - * Returns the X axis labels alignment. - * - * @return X labels alignment - */ - public Align getXLabelsAlign() { - return xLabelsAlign; - } - - /** - * Sets the X axis labels alignment. - * - * @param align the X labels alignment - */ - public void setXLabelsAlign(Align align) { - xLabelsAlign = align; - } - - /** - * Returns the Y axis labels alignment. - * - * @param scale the renderer scale - * @return Y labels alignment - */ - public Align getYLabelsAlign(int scale) { - return yLabelsAlign[scale]; - } - - public void setYLabelsAlign(Align align) { - setYLabelsAlign(align, 0); - } - - public Align getYAxisAlign(int scale) { - return yAxisAlign[scale]; - } - - public void setYAxisAlign(Align align, int scale) { - yAxisAlign[scale] = align; - } - - /** - * Sets the Y axis labels alignment. - * - * @param align the Y labels alignment - */ - public void setYLabelsAlign(Align align, int scale) { - yLabelsAlign[scale] = align; - } - - public int getScalesCount() { - return scalesCount; - } - -} diff --git a/android-libraries/achartengine/src/org/achartengine/renderer/XYSeriesRenderer.java b/android-libraries/achartengine/src/org/achartengine/renderer/XYSeriesRenderer.java deleted file mode 100644 index 42e4808e2..000000000 --- a/android-libraries/achartengine/src/org/achartengine/renderer/XYSeriesRenderer.java +++ /dev/null @@ -1,128 +0,0 @@ -/** - * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.achartengine.renderer; - -import org.achartengine.chart.PointStyle; - -import android.graphics.Color; - -/** - * A renderer for the XY type series. - */ -public class XYSeriesRenderer extends SimpleSeriesRenderer { - /** If the chart points should be filled. */ - private boolean mFillPoints = false; - /** If the chart should be filled below its line. */ - private boolean mFillBelowLine = false; - /** The fill below the chart line color. */ - private int mFillColor = Color.argb(125, 0, 0, 200); - /** The point style. */ - private PointStyle mPointStyle = PointStyle.POINT; - /** The chart line width. */ - private float mLineWidth = 1; - - /** - * Returns if the chart should be filled below the line. - * - * @return the fill below line status - */ - public boolean isFillBelowLine() { - return mFillBelowLine; - } - - /** - * Sets if the line chart should be filled below its line. Filling below the - * line transforms a line chart into an area chart. - * - * @param fill the fill below line flag value - */ - public void setFillBelowLine(boolean fill) { - mFillBelowLine = fill; - } - - /** - * Returns if the chart points should be filled. - * - * @return the points fill status - */ - public boolean isFillPoints() { - return mFillPoints; - } - - /** - * Sets if the chart points should be filled. - * - * @param fill the points fill flag value - */ - public void setFillPoints(boolean fill) { - mFillPoints = fill; - } - - /** - * Returns the fill below line color. - * - * @return the fill below line color - */ - public int getFillBelowLineColor() { - return mFillColor; - } - - /** - * Sets the fill below the line color. - * - * @param color the fill below line color - */ - public void setFillBelowLineColor(int color) { - mFillColor = color; - } - - /** - * Returns the point style. - * - * @return the point style - */ - public PointStyle getPointStyle() { - return mPointStyle; - } - - /** - * Sets the point style. - * - * @param style the point style - */ - public void setPointStyle(PointStyle style) { - mPointStyle = style; - } - - /** - * Returns the chart line width. - * - * @return the line width - */ - public float getLineWidth() { - return mLineWidth; - } - - /** - * Sets the chart line width. - * - * @param lineWidth the line width - */ - public void setLineWidth(float lineWidth) { - mLineWidth = lineWidth; - } - -} diff --git a/android-libraries/achartengine/src/org/achartengine/renderer/package.html b/android-libraries/achartengine/src/org/achartengine/renderer/package.html deleted file mode 100644 index c9db0a454..000000000 --- a/android-libraries/achartengine/src/org/achartengine/renderer/package.html +++ /dev/null @@ -1,6 +0,0 @@ - -AChartEngine - -Provides renderer classes that keep the chart rendering / drawing styles. - - \ No newline at end of file diff --git a/android-libraries/achartengine/src/org/achartengine/tools/AbstractTool.java b/android-libraries/achartengine/src/org/achartengine/tools/AbstractTool.java deleted file mode 100644 index 99841ed70..000000000 --- a/android-libraries/achartengine/src/org/achartengine/tools/AbstractTool.java +++ /dev/null @@ -1,111 +0,0 @@ -/** - * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.achartengine.tools; - -import org.achartengine.chart.AbstractChart; -import org.achartengine.chart.XYChart; -import org.achartengine.renderer.XYMultipleSeriesRenderer; - -/** - * Abstract class for being extended by graphical view tools. - */ -public abstract class AbstractTool { - /** The chart. */ - protected AbstractChart mChart; - /** The renderer. */ - protected XYMultipleSeriesRenderer mRenderer; - - /** - * Abstract tool constructor. - * - * @param chart the chart - */ - public AbstractTool(AbstractChart chart) { - mChart = chart; - if (chart instanceof XYChart) { - mRenderer = ((XYChart) chart).getRenderer(); - } - } - - /** - * Returns the current chart range. - * - * @param scale the scale - * @return the chart range - */ - public double[] getRange(int scale) { - double minX = mRenderer.getXAxisMin(scale); - double maxX = mRenderer.getXAxisMax(scale); - double minY = mRenderer.getYAxisMin(scale); - double maxY = mRenderer.getYAxisMax(scale); - return new double[] { minX, maxX, minY, maxY }; - } - - /** - * Sets the range to the calculated one, if not already set. - * - * @param range the range - * @param scale the scale - */ - public void checkRange(double[] range, int scale) { - if (mChart instanceof XYChart) { - double[] calcRange = ((XYChart) mChart).getCalcRange(scale); - if (calcRange != null) { - if (!mRenderer.isMinXSet(scale)) { - range[0] = calcRange[0]; - mRenderer.setXAxisMin(range[0], scale); - } - if (!mRenderer.isMaxXSet(scale)) { - range[1] = calcRange[1]; - mRenderer.setXAxisMax(range[1], scale); - } - if (!mRenderer.isMinYSet(scale)) { - range[2] = calcRange[2]; - mRenderer.setYAxisMin(range[2], scale); - } - if (!mRenderer.isMaxYSet(scale)) { - range[3] = calcRange[3]; - mRenderer.setYAxisMax(range[3], scale); - } - } - } - } - - /** - * Sets a new range on the X axis. - * - * @param min the minimum value - * @param max the maximum value - * @param scale the scale - */ - protected void setXRange(double min, double max, int scale) { - mRenderer.setXAxisMin(min, scale); - mRenderer.setXAxisMax(max, scale); - } - - /** - * Sets a new range on the Y axis. - * - * @param min the minimum value - * @param max the maximum value - * @param scale the scale - */ - protected void setYRange(double min, double max, int scale) { - mRenderer.setYAxisMin(min, scale); - mRenderer.setYAxisMax(max, scale); - } - -} diff --git a/android-libraries/achartengine/src/org/achartengine/tools/FitZoom.java b/android-libraries/achartengine/src/org/achartengine/tools/FitZoom.java deleted file mode 100644 index 92f67b840..000000000 --- a/android-libraries/achartengine/src/org/achartengine/tools/FitZoom.java +++ /dev/null @@ -1,78 +0,0 @@ -/** - * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.achartengine.tools; - -import org.achartengine.chart.AbstractChart; -import org.achartengine.chart.RoundChart; -import org.achartengine.chart.XYChart; -import org.achartengine.model.XYSeries; -import org.achartengine.renderer.DefaultRenderer; -import org.achartengine.util.MathHelper; - -public class FitZoom extends AbstractTool { - /** - * Builds an instance of the fit zoom tool. - * - * @param chart the XY chart - */ - public FitZoom(AbstractChart chart) { - super(chart); - } - - /** - * Apply the tool. - */ - public void apply() { - if (mChart instanceof XYChart) { - if (((XYChart) mChart).getDataset() == null) { - return; - } - int scales = mRenderer.getScalesCount(); - if (mRenderer.isInitialRangeSet()) { - for (int i = 0; i < scales; i++) { - if (mRenderer.isInitialRangeSet(i)) { - mRenderer.setRange(mRenderer.getInitialRange(i), i); - } - } - } else { - XYSeries[] series = ((XYChart) mChart).getDataset().getSeries(); - double[] range = null; - int length = series.length; - if (length > 0) { - for (int i = 0; i < scales; i++) { - range = new double[] { MathHelper.NULL_VALUE, -MathHelper.NULL_VALUE, - MathHelper.NULL_VALUE, -MathHelper.NULL_VALUE }; - for (int j = 0; j < length; j++) { - if (i == series[j].getScaleNumber()) { - range[0] = Math.min(range[0], series[j].getMinX()); - range[1] = Math.max(range[1], series[j].getMaxX()); - range[2] = Math.min(range[2], series[j].getMinY()); - range[3] = Math.max(range[3], series[j].getMaxY()); - } - } - double marginX = Math.abs(range[1] - range[0]) / 40; - double marginY = Math.abs(range[3] - range[2]) / 40; - mRenderer.setRange(new double[] { range[0] - marginX, range[1] + marginX, - range[2] - marginY, range[3] + marginY }, i); - } - } - } - } else { - DefaultRenderer renderer = ((RoundChart) mChart).getRenderer(); - renderer.setScale(renderer.getOriginalScale()); - } - } -} diff --git a/android-libraries/achartengine/src/org/achartengine/tools/Pan.java b/android-libraries/achartengine/src/org/achartengine/tools/Pan.java deleted file mode 100644 index 2d4ea28e3..000000000 --- a/android-libraries/achartengine/src/org/achartengine/tools/Pan.java +++ /dev/null @@ -1,163 +0,0 @@ -/** - * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.achartengine.tools; - -import java.util.ArrayList; -import java.util.List; - -import org.achartengine.chart.AbstractChart; -import org.achartengine.chart.RoundChart; -import org.achartengine.chart.XYChart; - -/** - * The pan tool. - */ -public class Pan extends AbstractTool { - /** The pan listeners. */ - private List mPanListeners = new ArrayList(); - /** Pan limits reached on the X axis. */ - private boolean limitsReachedX = false; - /** Pan limits reached on the X axis. */ - private boolean limitsReachedY = false; - - /** - * Builds and instance of the pan tool. - * - * @param chart the XY chart - */ - public Pan(AbstractChart chart) { - super(chart); - } - - /** - * Apply the tool. - * - * @param oldX the previous location on X axis - * @param oldY the previous location on Y axis - * @param newX the current location on X axis - * @param newY the current location on the Y axis - */ - public void apply(float oldX, float oldY, float newX, float newY) { - boolean notLimitedUp = true; - boolean notLimitedBottom = true; - boolean notLimitedLeft = true; - boolean notLimitedRight = true; - if (mChart instanceof XYChart) { - int scales = mRenderer.getScalesCount(); - double[] limits = mRenderer.getPanLimits(); - boolean limited = limits != null && limits.length == 4; - XYChart chart = (XYChart) mChart; - for (int i = 0; i < scales; i++) { - double[] range = getRange(i); - double[] calcRange = chart.getCalcRange(i); - if (limitsReachedX - && limitsReachedY - && (range[0] == range[1] && calcRange[0] == calcRange[1] || range[2] == range[3] - && calcRange[2] == calcRange[3])) { - return; - } - checkRange(range, i); - - double[] realPoint = chart.toRealPoint(oldX, oldY, i); - double[] realPoint2 = chart.toRealPoint(newX, newY, i); - double deltaX = realPoint[0] - realPoint2[0]; - double deltaY = realPoint[1] - realPoint2[1]; - double ratio = getAxisRatio(range); - if (chart.isVertical(mRenderer)) { - double newDeltaX = -deltaY * ratio; - double newDeltaY = deltaX / ratio; - deltaX = newDeltaX; - deltaY = newDeltaY; - } - if (mRenderer.isPanXEnabled()) { - if (limits != null) { - if (notLimitedLeft) { - notLimitedLeft = limits[0] <= range[0] + deltaX; - } - if (notLimitedRight) { - notLimitedRight = limits[1] >= range[1] + deltaX; - } - } - if (!limited || (notLimitedLeft && notLimitedRight)) { - setXRange(range[0] + deltaX, range[1] + deltaX, i); - limitsReachedX = false; - } else { - limitsReachedX = true; - } - } - if (mRenderer.isPanYEnabled()) { - if (limits != null) { - if (notLimitedBottom) { - notLimitedBottom = limits[2] <= range[2] + deltaY; - } - if (notLimitedUp) { - notLimitedUp = limits[3] >= range[3] + deltaY; - } - } - if (!limited || (notLimitedBottom && notLimitedUp)) { - setYRange(range[2] + deltaY, range[3] + deltaY, i); - limitsReachedY = false; - } else { - limitsReachedY = true; - } - } - } - } else { - RoundChart chart = (RoundChart) mChart; - chart.setCenterX(chart.getCenterX() + (int) (newX - oldX)); - chart.setCenterY(chart.getCenterY() + (int) (newY - oldY)); - } - notifyPanListeners(); - } - - /** - * Return the X / Y axis range ratio. - * - * @param range the axis range - * @return the ratio - */ - private double getAxisRatio(double[] range) { - return Math.abs(range[1] - range[0]) / Math.abs(range[3] - range[2]); - } - - /** - * Notify the pan listeners about a pan. - */ - private synchronized void notifyPanListeners() { - for (PanListener listener : mPanListeners) { - listener.panApplied(); - } - } - - /** - * Adds a new pan listener. - * - * @param listener pan listener - */ - public synchronized void addPanListener(PanListener listener) { - mPanListeners.add(listener); - } - - /** - * Removes a pan listener. - * - * @param listener pan listener - */ - public synchronized void removePanListener(PanListener listener) { - mPanListeners.add(listener); - } - -} diff --git a/android-libraries/achartengine/src/org/achartengine/tools/PanListener.java b/android-libraries/achartengine/src/org/achartengine/tools/PanListener.java deleted file mode 100644 index d3d136c00..000000000 --- a/android-libraries/achartengine/src/org/achartengine/tools/PanListener.java +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.achartengine.tools; - -/** - * A pan listener. - */ -public interface PanListener { - - /** - * Called when a pan change is triggered. - */ - void panApplied(); - -} diff --git a/android-libraries/achartengine/src/org/achartengine/tools/Zoom.java b/android-libraries/achartengine/src/org/achartengine/tools/Zoom.java deleted file mode 100644 index 0abee92c8..000000000 --- a/android-libraries/achartengine/src/org/achartengine/tools/Zoom.java +++ /dev/null @@ -1,189 +0,0 @@ -/** - * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.achartengine.tools; - -import java.util.ArrayList; -import java.util.List; - -import org.achartengine.chart.AbstractChart; -import org.achartengine.chart.RoundChart; -import org.achartengine.chart.XYChart; -import org.achartengine.renderer.DefaultRenderer; - -/** - * The zoom tool. - */ -public class Zoom extends AbstractTool { - /** A flag to be used to know if this is a zoom in or out. */ - private boolean mZoomIn; - /** The zoom rate. */ - private float mZoomRate; - /** The zoom listeners. */ - private List mZoomListeners = new ArrayList(); - /** Zoom limits reached on the X axis. */ - private boolean limitsReachedX = false; - /** Zoom limits reached on the Y axis. */ - private boolean limitsReachedY = false; - - /** Zoom on X axis and Y axis */ - public static final int ZOOM_AXIS_XY = 0; - /** Zoom on X axis independently */ - public static final int ZOOM_AXIS_X = 1; - /** Zoom on Y axis independently */ - public static final int ZOOM_AXIS_Y = 2; - - - /** - * Builds the zoom tool. - * - * @param chart the chart - * @param in zoom in or out - * @param rate the zoom rate - */ - public Zoom(AbstractChart chart, boolean in, float rate) { - super(chart); - mZoomIn = in; - setZoomRate(rate); - } - - /** - * Sets the zoom rate. - * - * @param rate - */ - public void setZoomRate(float rate) { - mZoomRate = rate; - } - - /** - * Apply the zoom. - */ - public void apply(int zoom_axis) { - if (mChart instanceof XYChart) { - int scales = mRenderer.getScalesCount(); - for (int i = 0; i < scales; i++) { - double[] range = getRange(i); - checkRange(range, i); - double[] limits = mRenderer.getZoomLimits(); - - double centerX = (range[0] + range[1]) / 2; - double centerY = (range[2] + range[3]) / 2; - double newWidth = range[1] - range[0]; - double newHeight = range[3] - range[2]; - double newXMin = centerX - newWidth / 2; - double newXMax = centerX + newWidth / 2; - double newYMin = centerY - newHeight / 2; - double newYMax = centerY + newHeight / 2; - - // if already reached last zoom, then it will always set to reached - if (i == 0) { - limitsReachedX = limits != null && (newXMin <= limits[0] || newXMax >= limits[1]); - limitsReachedY = limits != null && (newYMin <= limits[2] || newYMax >= limits[3]); - } - - if (mZoomIn) { - if (mRenderer.isZoomXEnabled() && // zoom in on X axis - (zoom_axis == ZOOM_AXIS_X || zoom_axis == ZOOM_AXIS_XY)) { - if (limitsReachedX && mZoomRate < 1) { - // ignore pinch zoom out once reached X limit - } else { - newWidth /= mZoomRate; - } - } - - if (mRenderer.isZoomYEnabled() && // zoom in on Y axis - (zoom_axis == ZOOM_AXIS_Y || zoom_axis == ZOOM_AXIS_XY)) { - if (limitsReachedY && mZoomRate < 1) { - } else { - newHeight /= mZoomRate; - } - } - } else { - if (mRenderer.isZoomXEnabled() && !limitsReachedX && // zoom out on X axis - (zoom_axis == ZOOM_AXIS_X || zoom_axis == ZOOM_AXIS_XY)) { - newWidth *= mZoomRate; - } - - if (mRenderer.isZoomYEnabled() && !limitsReachedY && // zoom out on Y axis - (zoom_axis == ZOOM_AXIS_Y || zoom_axis == ZOOM_AXIS_XY)) { - newHeight *= mZoomRate; - } - } - - if (mRenderer.isZoomXEnabled() && - (zoom_axis == ZOOM_AXIS_X || zoom_axis == ZOOM_AXIS_XY)) { - newXMin = centerX - newWidth / 2; - newXMax = centerX + newWidth / 2; - setXRange(newXMin, newXMax, i); - } - if (mRenderer.isZoomYEnabled() && - (zoom_axis == ZOOM_AXIS_Y || zoom_axis == ZOOM_AXIS_XY)) { - newYMin = centerY - newHeight / 2; - newYMax = centerY + newHeight / 2; - setYRange(newYMin, newYMax, i); - } - } - } else { - DefaultRenderer renderer = ((RoundChart) mChart).getRenderer(); - if (mZoomIn) { - renderer.setScale(renderer.getScale() * mZoomRate); - } else { - renderer.setScale(renderer.getScale() / mZoomRate); - } - } - notifyZoomListeners(new ZoomEvent(mZoomIn, mZoomRate)); - } - - - /** - * Notify the zoom listeners about a zoom change. - * - * @param e the zoom event - */ - private synchronized void notifyZoomListeners(ZoomEvent e) { - for (ZoomListener listener : mZoomListeners) { - listener.zoomApplied(e); - } - } - - /** - * Notify the zoom listeners about a zoom reset. - */ - public synchronized void notifyZoomResetListeners() { - for (ZoomListener listener : mZoomListeners) { - listener.zoomReset(); - } - } - - /** - * Adds a new zoom listener. - * - * @param listener zoom listener - */ - public synchronized void addZoomListener(ZoomListener listener) { - mZoomListeners.add(listener); - } - - /** - * Removes a zoom listener. - * - * @param listener zoom listener - */ - public synchronized void removeZoomListener(ZoomListener listener) { - mZoomListeners.add(listener); - } - -} diff --git a/android-libraries/achartengine/src/org/achartengine/tools/ZoomEvent.java b/android-libraries/achartengine/src/org/achartengine/tools/ZoomEvent.java deleted file mode 100644 index bd8fb686f..000000000 --- a/android-libraries/achartengine/src/org/achartengine/tools/ZoomEvent.java +++ /dev/null @@ -1,56 +0,0 @@ -/** - * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.achartengine.tools; - - -/** - * A zoom event. - */ -public class ZoomEvent { - /** A flag to be used to know if this is a zoom in or out. */ - private boolean mZoomIn; - /** The zoom rate. */ - private float mZoomRate; - - /** - * Builds the zoom tool. - * - * @param in zoom in or out - * @param rate the zoom rate - */ - public ZoomEvent(boolean in, float rate) { - mZoomIn = in; - mZoomRate = rate; - } - - /** - * Returns the zoom type. - * - * @return true if zoom in, false otherwise - */ - public boolean isZoomIn() { - return mZoomIn; - } - - /** - * Returns the zoom rate. - * - * @return the zoom rate - */ - public float getZoomRate() { - return mZoomRate; - } -} diff --git a/android-libraries/achartengine/src/org/achartengine/tools/ZoomListener.java b/android-libraries/achartengine/src/org/achartengine/tools/ZoomListener.java deleted file mode 100644 index 4827483ea..000000000 --- a/android-libraries/achartengine/src/org/achartengine/tools/ZoomListener.java +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.achartengine.tools; - -/** - * A zoom listener. - */ -public interface ZoomListener { - - /** - * Called when a zoom change is triggered. - * @param e the zoom event - */ - void zoomApplied(ZoomEvent e); - - /** - * Called when a zoom reset is done. - */ - void zoomReset(); -} diff --git a/android-libraries/achartengine/src/org/achartengine/util/IndexXYMap.java b/android-libraries/achartengine/src/org/achartengine/util/IndexXYMap.java deleted file mode 100644 index f95726222..000000000 --- a/android-libraries/achartengine/src/org/achartengine/util/IndexXYMap.java +++ /dev/null @@ -1,108 +0,0 @@ -/** - * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.achartengine.util; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.TreeMap; - -/** - * This class requires sorted x values - */ -public class IndexXYMap extends TreeMap { - private final List indexList = new ArrayList(); - - private double maxXDifference = 0; - - public IndexXYMap() { - super(); - } - - public V put(K key, V value) { - indexList.add(key); - updateMaxXDifference(); - return super.put(key, value); - } - - private void updateMaxXDifference() { - if (indexList.size() < 2) { - maxXDifference = 0; - return; - } - - if (Math.abs((Double) indexList.get(indexList.size() - 1) - - (Double) indexList.get(indexList.size() - 2)) > maxXDifference) - maxXDifference = Math.abs((Double) indexList.get(indexList.size() - 1) - - (Double) indexList.get(indexList.size() - 2)); - } - - public double getMaxXDifference() { - return maxXDifference; - } - - public void clear() { - updateMaxXDifference(); - super.clear(); - indexList.clear(); - } - - /** - * Returns X-value according to the given index - * - * @param index - * @return the X value - */ - public K getXByIndex(int index) { - return indexList.get(index); - } - - /** - * Returns Y-value according to the given index - * - * @param index - * @return the Y value - */ - public V getYByIndex(int index) { - K key = indexList.get(index); - return this.get(key); - } - - /** - * Returns XY-entry according to the given index - * - * @param index - * @return the X and Y values - */ - public XYEntry getByIndex(int index) { - K key = indexList.get(index); - return new XYEntry(key, this.get(key)); - } - - /** - * Removes entry from map by index - * - * @param index - */ - public XYEntry removeByIndex(int index) { - K key = indexList.remove(index); - return new XYEntry(key, this.remove(key)); - } - - public int getIndexForKey(K key) { - return Collections.binarySearch(indexList, key, null); - } -} diff --git a/android-libraries/achartengine/src/org/achartengine/util/MathHelper.java b/android-libraries/achartengine/src/org/achartengine/util/MathHelper.java deleted file mode 100644 index f5b893bf7..000000000 --- a/android-libraries/achartengine/src/org/achartengine/util/MathHelper.java +++ /dev/null @@ -1,174 +0,0 @@ -/** - * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.achartengine.util; - -import java.text.NumberFormat; -import java.text.ParseException; -import java.util.ArrayList; -import java.util.List; - -/** - * Utility class for math operations. - */ -public class MathHelper { - /** A value that is used a null value. */ - public static final double NULL_VALUE = Double.MAX_VALUE; - /** - * A number formatter to be used to make sure we have a maximum number of - * fraction digits in the labels. - */ - private static final NumberFormat FORMAT = NumberFormat.getNumberInstance(); - - private MathHelper() { - // empty constructor - } - - /** - * Calculate the minimum and maximum values out of a list of doubles. - * - * @param values the input values - * @return an array with the minimum and maximum values - */ - public static double[] minmax(List values) { - if (values.size() == 0) { - return new double[2]; - } - double min = values.get(0); - double max = min; - int length = values.size(); - for (int i = 1; i < length; i++) { - double value = values.get(i); - min = Math.min(min, value); - max = Math.max(max, value); - } - return new double[] { min, max }; - } - - /** - * Computes a reasonable set of labels for a data interval and number of - * labels. - * - * @param start start value - * @param end final value - * @param approxNumLabels desired number of labels - * @return collection containing {start value, end value, increment} - */ - public static List getLabels(final double start, final double end, - final int approxNumLabels) { - FORMAT.setMaximumFractionDigits(5); - List labels = new ArrayList(); - double[] labelParams = computeLabels(start, end, approxNumLabels); - // when the start > end the inc will be negative so it will still work - int numLabels = 1 + (int) ((labelParams[1] - labelParams[0]) / labelParams[2]); - // we want the range to be inclusive but we don't want to blow up when - // looping for the case where the min and max are the same. So we loop - // on - // numLabels not on the values. - for (int i = 0; i < numLabels; i++) { - double z = labelParams[0] + i * labelParams[2]; - try { - // this way, we avoid a label value like 0.4000000000000000001 instead - // of 0.4 - z = FORMAT.parse(FORMAT.format(z)).doubleValue(); - } catch (ParseException e) { - // do nothing here - } - labels.add(z); - } - return labels; - } - - /** - * Computes a reasonable number of labels for a data range. - * - * @param start start value - * @param end final value - * @param approxNumLabels desired number of labels - * @return double[] array containing {start value, end value, increment} - */ - private static double[] computeLabels(final double start, final double end, - final int approxNumLabels) { - if (Math.abs(start - end) < 0.0000001f) { - return new double[] { start, start, 0 }; - } - double s = start; - double e = end; - boolean switched = false; - if (s > e) { - switched = true; - double tmp = s; - s = e; - e = tmp; - } - double xStep = roundUp(Math.abs(s - e) / approxNumLabels); - // Compute x starting point so it is a multiple of xStep. - double xStart = xStep * Math.ceil(s / xStep); - double xEnd = xStep * Math.floor(e / xStep); - if (switched) { - return new double[] { xEnd, xStart, -1.0 * xStep }; - } - return new double[] { xStart, xEnd, xStep }; - } - - /** - * Given a number, round up to the nearest power of ten times 1, 2, or 5. The - * argument must be strictly positive. - */ - private static double roundUp(final double val) { - int exponent = (int) Math.floor(Math.log10(val)); - double rval = val * Math.pow(10, -exponent); - if (rval > 5.0) { - rval = 10.0; - } else if (rval > 2.0) { - rval = 5.0; - } else if (rval > 1.0) { - rval = 2.0; - } - rval *= Math.pow(10, exponent); - return rval; - } - - /** - * Transforms a list of Float values into an array of float. - * - * @param values the list of Float - * @return the array of floats - */ - public static float[] getFloats(List values) { - int length = values.size(); - float[] result = new float[length]; - for (int i = 0; i < length; i++) { - result[i] = values.get(i).floatValue(); - } - return result; - } - - /** - * Transforms a list of Double values into an array of double. - * - * @param values the list of Double - * @return the array of doubles - */ - public static double[] getDoubles(List values) { - int length = values.size(); - double[] result = new double[length]; - for (int i = 0; i < length; i++) { - result[i] = values.get(i).doubleValue(); - } - return result; - } - -} diff --git a/android-libraries/achartengine/src/org/achartengine/util/XYEntry.java b/android-libraries/achartengine/src/org/achartengine/util/XYEntry.java deleted file mode 100644 index 53761a4d1..000000000 --- a/android-libraries/achartengine/src/org/achartengine/util/XYEntry.java +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.achartengine.util; - -import java.util.Map.Entry; - -/** - * A map entry value encapsulating an XY point. - */ -public class XYEntry implements Entry { - private final K key; - - private V value; - - public XYEntry(K key, V value) { - this.key = key; - this.value = value; - } - - public K getKey() { - return key; - } - - public V getValue() { - return value; - } - - public V setValue(V object) { - this.value = object; - return this.value; - } -} \ No newline at end of file diff --git a/android-libraries/achartengine/src/org/achartengine/util/package.html b/android-libraries/achartengine/src/org/achartengine/util/package.html deleted file mode 100644 index da92e9133..000000000 --- a/android-libraries/achartengine/src/org/achartengine/util/package.html +++ /dev/null @@ -1,6 +0,0 @@ - -AChartEngine - -Utility classes that provide helper methods used by most of the other packages. - - \ No newline at end of file diff --git a/android/.classpath b/android/.classpath deleted file mode 100644 index 07677d89f..000000000 --- a/android/.classpath +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/android/.project b/android/.project deleted file mode 100644 index 94894b517..000000000 --- a/android/.project +++ /dev/null @@ -1,45 +0,0 @@ - - - OpenRocket-android - - - - - - com.android.ide.eclipse.adt.ResourceManagerBuilder - - - - - com.android.ide.eclipse.adt.PreCompilerBuilder - - - - - org.eclipse.jdt.core.javabuilder - - - - - com.android.ide.eclipse.adt.ApkBuilder - - - - - - com.android.ide.eclipse.adt.AndroidNature - org.eclipse.jdt.core.javanature - - - - core - 2 - WORKSPACE_LOC/OpenRocket/src - - - core-resources - 2 - WORKSPACE_LOC/OpenRocket/resources - - - diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml deleted file mode 100644 index 76922cdca..000000000 --- a/android/AndroidManifest.xml +++ /dev/null @@ -1,87 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/android/libs/android-support-v4.jar b/android/libs/android-support-v4.jar deleted file mode 100644 index 1fbeba0932023ad6f4b851f533261eee0cb66798..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 271788 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

2{d8Do1ByJQa(4NyF4LRmP+Y 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

O0gkx4}gZP6o&Ac5xTsN zJftHP0RnJ?oS}x&-vYBSXten;t@;{26dy#a$n&cN%Qxz*s-M=$lGHA{x_uHsn?;~# zw_YO7FAp~Y47tZnQoc_fc=|@87qTPaM(i(yDR?z9rM_SthF9Uy;&@_eJKp6MgtaDYf6SWciN66{*DtyU zM51k5)c&)>U#0eM>S(2mt%|l~UeB|UVh1IM_ySp(6^ci~9N8rkW=emaSFL8P7=*#v z$VXbzTFKg_pog3K&4JJjt=NL>J95_-mENN@W)t{&deGAv|7gJn!mvF;do6_dlReB! zlXg+l&f+t|%t+;@&Te4613Yc=U>DR5gAUUQLf&(cA~OS`Ih5dsR-~S*7Zk1<7|^>d zr!iq`tKG{vr=cDb8(TYqi*1#T9CY;o`QsJvXTB0m-PgK3(J&~f-@=50XxtdB<-ody zl(I|jhin;(nW0t|y@C^(qELmxa$RrC3JQKt>bAV%KoNcnE2`IjV{XQb*0a%BMkBr} zQvY#EHCX5~Tf7I{C$$Xly+m`Zmb)y)2`JBxFZR*&7oX2kr-es3H43zJakgs!n%oe98_sG z@^4U=IqBXNC^`FVVICG1IWb+y9$u2d4-^IoD#lzY^q|kl>vD{SzS!6w;c{2AY`<{L zW+QCt)fzVt`eTyBzbwt84wd};Lm2b&h;Gi{p}5u#ImJ#mtw+tc;YI-;&W&~6PzSP{cNftE z5JTP;zzbkyjrBQQCxCv*)X*wT0>fU`tFmXB4Ae(7dcvGV-`iK)=1VxF& zGK=CEWXT$_7f1y!zO{XkkW`hyv5I(F${rDhX>QmZ)Zk|cU8zB$9JZ%#kU(6 zJzL}*kP;(>hpH8R@pAkOSph#nIBzoe`!)qHKu}LFR7Ipe=X>~889YCnGrvVr6O3^U zZHQn?PSQ&*r6;pw8tE#onY)*34rq=fo!~llGT&iqj!bP!Cxfxns?p0&Zl`SKCTmY< zcUrR&p69$FlJc?T7L&&<9*1g7KzMY3+#dC-l;`#;I=COwK1QnnZx^mWvWAz(s=YTwtEjCf#iz(~*h`HX#sW9Gb z&EfKVmiqSDBY|^qGwsUgSOcQ84Pf=hnb*SO`SSr+1Ua6zyJ{(1+Sai2-~qSYutZSV zM+(3A0FrYMa=}o_f0yyR0>cZDC=o5lM0tK7VkDli{NtBI?>lz2{4-JA|5d8>Kd7+( zG5fx(PR4;ihtI7s*9$j-Zb=Y%=iE9FU#+O z_-~`Z5_fZBL$aWM9Jz?pKs3)3Cvvx!>|e2ZQFKR!xkGuma~9liKzSASJ`eF@bdMc4 z%eF;xJI^0yxriLTLwi|s8r;2u^?csaCh+iP1A=(Rm|@eu^ec3Qaf6=Plfn$$3PXLB zjKU%&Fvm9!_ltD#WEtKQJg|uY;xN4K6Z06|kd%DK2Q0{gc(Y>@-x-^%)DwGCXYovH zhXhZ*OiOOTPeVH8%Ue?W_EM+k>>=ZS97zpg8^ z1VeN)zgkOtt-E}2gJI-&0e^7_y4BAPJ8Jto&On&<@qIg@#-7$V$Jz2`-@(T*7b}j$4(=wtt1kOlYWI zvjl1-L!8QWAp}a&P%=4a$2_l23L@1e&teRQaYC@J#7+Vo({#CKOYZcj1svfuDxMXb)5+qss z2vWGD?B7+QA{DWFDuSKy(jzE&1q?kw&JH4_p>Rb#CdsCtB2Du!hSK0^B*g@!^t_;; z*Hd}(Fh|DAHy2qFW|>JLKXvKWUyoM2L`Z-68S~b{B^AI@^Fkpe7it6FESLvTFl{S`IY1m%jMmT@gUqBIkPW zm@WW5u<_#1v+UvVbN-pO8|-EM$kD>4A0#L!j!xUF!CQm!9kQcLO{3cj!HbGhd_~^9 zOCiH%8Kjfv)CFr`k{^&Sa#@3$9;iPxP%92MKE40rnZ+^)3G{h9a1E38%8DLjY`TUj zc^gOOr5lzkc^gKiRaok68n!HP%MRe#k7S*;r(EO`e&mr}v89;s&J=r(`Sy{--A&;2 znPqo9a}4|NO5nLwIPGq`=Xp!Q?}2Mru_UQGQ%<-tvv6TC@!{4?j!2dUQTYSs(NbY zEO<5-HaBRVoT!*EnW5a~B&GU_P~PRNliQsOVoO?ORmG1~Qyi!zZm;R7YfE~t&R$(r zicS|%UZTFdV{QeG=j2-ZCgC{S*ix9=tE_mPO^+o^43q?fL2#oybT*tLo%2BH&E)5> zs|Q5dj&7Xs$6ZL9Uy@WsS$<_X<=}cM1ouWA|30oC$OS5TGynK&kabU>sw4LxF?Vsh-+;c+#Gj5$%L;YwJ{Z;mooO>J9v* zm_L7HubZ|#EfQ0M!RbUDLIpW>XwXqroqOuwq2c}Vlv7eZRjk@ETcwbDP85ia znI^yHy+cDc8$mK%3{fuzlI^vtBlOo@5^o|;LjbFI5Sz+nx%Ls{qU>r_!sPk6P3gh2 zjbZ{Y#(C(h;+LZ%G&Pk0E%|YQ+Vxp9EyznE7ZgQ>dLc4dORfuseOVi`mPIE5H>J>c`ejMiiDNFqTx{O^l2b z8#bNA4yM#YO#@SkP+@jsQe(+AgQuJ*ss)Qo3op}sSaZtq_W12A9LL{1CGda~ZlFe^ z-vA;Ys(9YGEvw%62Z$KzY5lb535Nr;lA41~bD6Ovv*i}{B+PHJNJf+PZ)b#G3(y`qBdcWl8zKQX{?cPxzy1foXv zGkqA7kkngfTA0>ld&_FB(gpgFy9oyoMkqTPU9ga-+;q8YNwHS-j-O@*jnM?ZQjl&I>S^D zpu-Fie9)l}fg^4O1H1^01yLGNflnHy0NX;}enQ^-qMmTi{Wsi$Ijnx3j&LlMK}UTE zV$)_>^qAj~7gqlEygLd)jZA(5b6B(sS;T9%6f<-2`t+EC5l@TMYL{RDotemz zUq^@+bub9XUTJ^L>vAGbs=CuABU_K^k4~Ke`ue%@VCn3ds)r`~<)sJuv2A6{>pJj! z3*t3u!8I4(a;k@zCNtuzTk4Pvxzemfq6gL_IB?hm(z^eW=~=f2v2JxFs#wm<04ri9 zfYlaFtf9_fe&(*}kixAWW3ByJHHLZ^FBI6M9Om+=`cG36?{s0%-S$gKwFSn8>mK$}spwkT!He{}_X+$)#))OT z%b)r?QQuWH1Ux<8z}-S5CsA>m->QCHcEjXcB~m6hji-^(+E@|PuzL^%M%6Jzko*#} zkEoaOoYjLc$;b||clY?$VwG=u;Ox=Mur2-b-cORWTab#xPNq-?3@l)fT5N7;90mohE42c z^x&5;j`RRa15k!vaZyzfKH5!wv{YI)%H6!jY!woInA^p|n)n$BT*pLR1Y=qB`rs7= zxMnsRx1A>+od?diWfGbv3k3{5K-=$dbhhf2-~2TColI$d-DtG215?yXX=i1ZL7_Z@>h{4~ z*nTP++SdKIM-FF45c#q7zD14)i@3J^(#+}m_kqykA&FdAbLO4lL&R(SmGZ=0aWEWZ z__C@}&A1#C2)SCAyduC{5tM!TG7pj`WvwgnDf7_IdgMT-&fQk4=*w`jrGq@cR?-S0 zmZ(X#Q5i6Y*$Sc=`*_IluNkqP7=Dvp?%SqK(?JO4XK5IolZ)q-fGmVe8t_4S*#o&E z{ZviZVixFJ?vb_G0ZE0s!y*EWTo0)x2yy&|=ZLp>Me`Np7n@5e@Pqi)v04V`Ph4Qxzt>>OBnJ@YvG72=KAw5 zt_&x?cmun)v@3zQaffKnbm9GWC3`yQ*_~~Bn>sJ1YC2^Z=6R7H7aW4G=nu&(g|w%- z2`}#EltkXCmI$ORtwTJ@L*mOl`svj`PXJL_SO}~qOBWxXQk6XfYk-r<1RYyS1yo~X z8!Wgk@SbXdHAkIXR-iA0VB14CBf@Krk2U#+X@3Rab3fN8H9<197-Nl0;alUN&-q54$e)_(^bc5lJqtI)D!~EwZL6wjmf4@mv$0*g(*z z`jiOY*Cx;#=9w?BLMRfA=bpPXCIA~$5D;_eX1sdEES0jsw8qPTHrQOjt10i8WM^R; zLP9a#3YHecVUl#dXOtGK+5dY4aW$P?h}yPhSIvyp&>D7qbOxdrFQw|4cjcNr$Tu!o zO<(g(Cm1p$iF>8j^Hn*(Z}h6y6s8Phm$^b1lx=}+wBM;-ovSWd;%NkFb(uikQ0@5_ zd-ge;j~BKRCcsJb8D*!P58gai#wZkQcY^kjuD7nX+lu!JEOsgxD282(u+b=9(4Vu| zev=-X0}PHIZOVQyi4CkNs+}E>r`-ud9Cs_{D8c>6-ZG-IyKpF6pfrHHJ#D#xt?6yt zoT^~S%PaPlI*Q8ysS|;jpQH>te1j7BIsxR5u;vecyYRLR1H0V$$D|YJ6U9@KaFn5S z9`2N0jQfGXTL#}CerWq$ ziItMKpm;t{fR!$Io6#3WvMOe3plpHRP!0H`GU-a4l_v_qwgA5nFlJbye;UIaLGhhS zbcT?HDoR5WE016N%@3Qsr*dfftn@%TKa9SkH|-2{R3aXhD8Rfe#0 zBFcBTcv1otg}Pkp5`2L06p3i^IB*NOUN*Vw0biV1_ni(3Q;y&ut=OvKfD>aIRA`yZ zd5V2&2uWU&?Nw~JVVbbg2oZK`0_h)jyCa9EywC;1i`@_qMM^R)3xckUGkYlrS=Vhg z0s>r=WF^W>YhPA>7j01+sVVnya}wTBpb};zsFuH#C+N&$i`P&Cf^%ZO>GMDdfid%S zDOFl#{A$B=3OJ~01-dXavAClXtf3vT9p}I;<;BSV-hUy%8vIVpZ4Ba^C-AHrBKRzT zYGkwoaz`~gFCl6!28(s8xK4dBdc9N}?i68NtLtjn&lL;q=Zda~$AoH~B{&b|_?#h1 z0Qk6J-IE8TCVH@%aXgzp{2MF`GFz*+Ee19HHVO0k*)Yyl-fPFkX%{~bCE0+V4z3$^ z9jmpKozonHVO2DZGCnnw->jEuH@Ae4yy$a)zhH{(ic+~$d2n*(U?NJ%k^Y2~iT~%! zLajKF+&r*v;rI`R6E&pU0kgyGfosF0B^Y0~QOnyLd!rs1WFYL{9>MxD%}jd5ff zEv8qVts|Q3!b`nhBdfQY3!QQ0Gn1j>>nF4-(=OL)%(43c@Eu?DM`{NcG}2X+fG$d= z!;Dq*c1=C8XoSiBZ2oCca8_esl`EG~(2A!=16w=~e0ehqWj>lEFq(KnK-$RdUHrJX zytB8h)yO5bYi-8>0Zn3Z&f1i88{gQGdHh zvM@2WYh*{#6jy%q9OoUogUjJ#i{1hBolta#=+=d9x=B0QTD(8aU83yryitCO8sAq1 z@wO4){17x2Rw3I`QI!IW>uE)W&meT(E{dv;m5q`TE94=UElmSxgz2A8Sw?Uzr zZFC6C80UrJlemLvLa-^G5k>PmSZ&B2%rTk+EeKksx@VFadx>$oM+;)s9=sabZ`dgC zDI!UrlxM`KS6Zt*@!8~kV;z$b<((`<#}nlQV?80WpPGy1h5T6IB9HfXBH#}-Sdv#NBpss-1Xy_9-(4}Qfc6aHh~=mi~`(q0+H zGsmU#VRqzg*8IfrJQO!4N`v2Bkr3#}tcHlD&U7OeFvn%Y-S{*VBo-V4BJ?NwuRwJ> zC)L;cCRW!)i7wF_*RjuWyPeTt&-dY+cK}{l!q_>}{vY`KdXIQ&{=l0pPxT**UvA!D zbT&MF_>V3H?|%muYe6r2V|+HJthiil&eulUc|uP2u27#Id?Vbp1xOSL+*}00p`0p^xE3oXhx(zg~X@|^)o zGmkZ88hf=XtG;FE@{1bRPhMo3H^AMx&2S!&2hLo7`#lUL9nrU4F2F-4hJN;xM;w7| zZw$B%@gucfUMvwi(x(M@0aC9XRoZ(vMx(uMwg0iWz;`>OA&HkH!{_sarwFn%z8 zEmvEj8q`2!&s7xA8FaHyhE-jJz9>PvcN#}`%w860hX&*?e1zW2*-Eu3Ptqa;x@5^I zWg}1?La>xu2vtYq`V%tCK#XY+)z&LHlABCp_`*Z}XeCGQVDUSMS~hrOv*S%6$L5Ce z9m8iQTPhJ-foHisN_W#QoO4JfgTG=(~brI+HwdzzdE1NW%HYskRHubYfahB<2_Ej;r2Xq-LWs+q0O@)KZ!wjJ+ zs7qkRvjAxlJ+P7nCjn0i|9)QI9q}xvpV}h}7WW3MuWYwe^nCepb&lOsW&QKwVVwZJ8 zm+JdNE*WPS)lG!Ak<=tqiX^O(-_HrxA04S+qOtDQi~68cg7uQ-f~p&#-xI>OFoN6X z7aeih54xtLO3c$D-_{H|TSS}OTcXm@C_hZKw4}Fo3^OO%^4a(SI0kJTEJyl9gp$ob z;-$LQp)ctrauKXw4N*!%7fqD;s44d{;;9F9&!NI2t~npYrs=R-H)A(Tvp>!KGP0fo z)#yH&w12BrnzYkj=*GIoOF17G-BJGhw3gU-c>6Ek2d={Q&(YFN2mI93@7upT!g_ny zjn5z;lSk&Qm~8)SDy@@aqSmw&B_Qd8VoFN;$gT4^zx67#IxYp7w^fx=+Rga63)b|~ zgHNr80S!mYizNaaa-OwlzKrz706e}>uQr}#&J;EiInlo&4YI_7!k^z}-hE;EKMa(o z!%(nik552?U@l_W>6o*ouf00PD_XwO>~gcwZH}f)l@ui;V8b`$1QCO_X9(sVnm{qf z?eFMi`Nk)fX9qttv6SAF;*a*NnOL3@&FcYWHMj-4Ae8#WRa~s?b;w%1aS3|0Q1|gYP%!AGB0{Z}QW-iT z_v39MzU+2{@^^8OF_1a3WD3x(?X(>K*D?U4zbnsfpd##6?Hu%ZUAB|oj66ziL*Mjt z-nJ-Fj&2mEz8E+M`?oi2$_ZEMrxj+hi}rAuvtQU^EjC^u2&P^ay_h1BgC}0X-a~W; zG`&Ikxr%Zt7Fq+0rczr=p2c6bs%Viay`_!Dvu8JYVPFHmwrJ8B*N@ZoObR5heSrK` zkS6$FLO!A_!zt&}7%FgR<^|i&y;79cb?5w5Z%ULbtz#^@t*eS%*yB`HcUC#hx9T+> zNpG7wN|f1?Q@K22yvyt4n@46mu;a(Vi8MBeGy`|j8i(OE9b9GKgR+;&0+HPdie10Q zmFut|qRUqn$u~{+9V0Wf%!`-tG!wL}ldW}F${vWF>H)7&D4Xjv!>rp^E6F=2rJh$# zFP+>#r_Ap|H^H@#5iOlt>im(*KTQY0;9G%++x%r~0ZUl7ju*H& zirvc`4IIuj22-vb)l}=`o@I-xpuRyz3vRUW7c@r-I>Z5pHv@17jKd6&bO6O{-fkW5 zi+5osSks@$_(mTlQQndqG4{s?dy8N#S2>`_WkIG#w$nxeNG=cX)D|>yKGx0bJen5) zK5=W@-X4~JPWPmrwND~SCn*F8&>i9R0SV!u0n*AFHE7tPB|H}4&Cwh|FGVgjJ=qrM zZK&@S_+(N`uBNWyi+iYbVU|Fsec-b^^9NH%b4aK&_H>Bvb9u-!4gB@8hW(@S z(b@IH;&$pe-BSbCvQm0d--EjD4xLCPCx~gHaE`X!x6@5gbH9(12+wbHX@b(!#MV=h zv!1B};`|n$&Op)*X#W*!9i(@E$VfiWNWLei(xx#%5w9hoeZBMpQJ7JZeiF*jhp9ic zj9;Dt$I>IQurlJ@0e_xqAqz!e#Nz)X5VMhT4QDmWrWsM#LQFB10J_P}!Kl9f4Kqpn z>MNuri|Xs>VYiTBfMYDi1_BI4`+$N9)spvCq@Anqf(gTR(#RcI3BMr1Tq7s+cQeFo zxY#$#gc3x7HutwE8#NE!9nU|!XF|Kc6fxTV%l=+$UIb-a1oZ^@RF`&&Y+UrpyyXdI z70j326K&($%y`2C_653dh@+YF&iao>TaXJHQUgJcwrGd;U;|=xSf_x%ETOwO2kS2G zo-Y4D^Tt7o+tDIeRyM&F03?~#50f@6-Rw;RvWDRkO#|&GcP2u&dS7mb{29bOe&SDO zSe@(})bK10&RRzD^m?w18*w)v^g^#hfg2;lmlWErkR8;X&#QFu)c$jik48l{El)QfLUixI z*arbEI4TIo2)+Rn?;r>_+$dVW9{TTm7v_j#{@esuXQh3Yg~)BZKEk;9KloDeeR!U) zT<*iOsN$#6cpGm$z`{Cr9UTYqaMg#dt-`q{q!O~P2c-!ywj&%6^LKH@B)iV%K%glnD)*Bkw@J=;n=-u}2>j z!sP`qPXB^t7*b3Na4BvBVnWnRNBAA+y|Jt44^B9d!Xrj15GZa#)|*I_>7K`!MyCpD zmr+rPWJ$VKufi0&N+$R$KbXA&YpufAH(^?QM-RjCs)APJ45YeeK_5FjE5w(GPZypnzI9N~91HVjKX>~?EiGBAt3$roxtp|NzDb+X*)0*a{os4db z;qS8r)Rq8>Xrr*zC$8q8l&?-G#2aBsYsyKwH?>IBr&g`*$&ju~27J@Ql$`kNCg7fM z#pp(><^@!nC1VE~2Bh77c!`jP4KH9ygBY|1&fQUyX6_pO%5B&%;yo075QzP#+cX5` ztF5Q7G-x^N9;2?b3T6TxHNTuoz1-<9C_|pRkX>{VPh6Cn-)(rgOv1?c9j_J+(3pu< zGj%0@PP+qFHKE@TFg@hRmOfp$pjK|dPT6xIAaYpD3qsT9$PR4xs*uuC+zZ8xWpppE zix?m`FjD#03@+ym@^q7nMId^f*~!i{=$aKD4ijRSLQ$2x@CBkqCskwxP-UHhTj z1=V#pzANkn65kQ`ctnwsTx~$`Le898ZB(r5%3ZA|?!u%#X|96&T>q=uQ2mA7iB5ak zYR~b)s>>H^pv?(efE;7h-UHD+HF)K`Beb(WeRa4a@YCP=D9(CUv?I0n*8UZ&D>C}< z_!j-+x7L*RQ1V^)3r1I_@_o1~V0S?FAkE;l;fIkITQ{Wr^KJR7ZdW|c@$yacYvTvM z7uL6*_H_3y%MH$pB;Q@SptV={$*^ZhmhEGRTBWmRzW#nrB-c zS{<~7dLCV=;AC2;8a3E{r1nQC(q^^Q5E}|{CpB*eHJTvKCjfR;Vi2nON~I^R4v4dV;@ zwRYNP;CGyjVL3s7cZR2Vo22d77Amb-?XA?2xXF zBU^Fd_5j_md#|4{qp&$$+#&B{{4Ld-5pQmAM>qT>)zLk6UnOyqdXNkcUtdK{UC0*{ zPtJ|r)jHojf0SFR=|~i=FegMa^zq(NJlUY>bur%Tw+Wh!dVW38JXt41ib^k7u3=iR znE#rMMcWmq&<{>B`uusod5C{jtw6;2N>mG*Iez8Ki8rt$96e7awb z;z!u={V@dqUE$Lw6y-oQ142I>oDMd9Qa>cq`?iAIU(nWv-2sv>oc7#bgqywFf$uLl z`*c6xxyQJDnIDR;P(RSV!(DdBq#&qJY(2w4uGqDw*z13|A1Ra>d08WX63$zDoJ(R* ziaH0NF-!E_D}k^KRLml=uGT^8K~zi*=#s`Bl*ahGC@lh7wblWWum@o*>$#btZ$W)z zcZ*@PHt)(?hwmS#@0DME$X@`BJ0f?7n}WbD?@9yM!J%Xof#CBr#MLJUF6x|x*Zrro z>%ceY4mf5G7^$>2K}ArGywCn(Kb+opB`fe zTc!}kU2y7y^L5j_eYm#gLD^1@D;H(1?VYf;1K+hc={?n4YSOX&U=qCULoZ5zZ$N(MmfPrH+>>QjmbaQ#$d`(N>ng;-;anAf9mL2n9aFx#$+{Z0F z+EKWb6M|#M1y+nriEuE764$5U^6S(jr{*ad6w9 z(+CqGHtusAxe8!+5zdPpTB?xAxO8 zHg(X$XIS3EpKI(qvUx@8pyS}w7dcw5i?rC`bVkO=fJ#pyM z-S*sp3fP4J7;r^H)EYOAGQYK{y3nx%WVhnIh%z0y>7WO;T5G32?dF9)xp6{eef;hV zfB&vWsIbcbHoWhAhvO1iO^?G86&~j7#M$}lw9B3CA%GG`vX3J}&Mi4@fMj59Q zEaq!J1%V7gO%3y_Q-BK8phI&BvvT8y4iXunbJK|SR~Zs_lQ`}JDg5z63c1TchxtV? zLPs*nfJf2@OdnnxHcq9LHP|Q&KaQlha%RY(L1j`eAvd*}N2*03p~g3Ds2aw0%^^3c zG350Ur`ESIB=AzCHl&LjxoRs6^r1{`B$E$t#mR zu?E2h7q01>pgvaz@AAdj5U@+i`p{FD%SVp+MnpIs7a{WnvM{`hIP)dckl{x@x^DDH4cv!ZtYNjPC$$JexS%8s!fU-IW?l_5K@k;7RfXMd*x8muC7h?5^*`= za{ziD->$$-Xp0yZku`EVOnYCuPQ#1fHJoXO$Mk){Ju?a}9b=Rin~fvO~qY z2pb{SOg3z`*>vDkBjjDsL;X|OL)*LTOY~FOL)E*&i@0l%7v*QE7wKoUD?a~2lJQc6 z{J~H0Y@oR0R8kw47|JV<`JuQWrAL7D%+lC)lP2*o!YHy!@Oi;D&fKH&vh+G0@S)=v z|4?kXAm#`Ep&^Tp_owfu$DPo86ZWZM9Add8re3_oa#L)*jZKa)s`3`w|(20fN^ub z$J~BsAel&;?9~Cbojs(v)AxYlY~K;2y$;7cTLJ*T^_nQi1N)=6O^}XrRoXWXmVUym zEXg|87mPEsu>boQb(JR&pSe~7nf3rggIShfwWp8n_3f1pE`h=&L%;uSM&Uk)ce zxw1l=%iDfH*rsdt<@ZgxvK0!NnH*1Zj1&kW4)#neDbtPLZYtJKn9W@UArnnVub2Z( zBOR>55g9rmB%WqWFcupu#F0BX1u0)$HWzI0-NNS&!V=Mw4mA@6y9{?#|7-W+(Iz)yW#X}5iJl3$EH>~M1o7@mjt_c~)Y1l?F z+IQAxr(`{Ba}>TQmPl&kUql)t{9%4MYJ{DGn$_`seRuB~s{LW4{Dgm6*nUcMeoU`U z>u=ylaAfGwTy3wcPha^bK>*>@UL@3|(vC>354JhM6E=Z(nQgw}#Wt~tGy1{=Pjm7(pUaM*D5ZF<@)ZN=}v>o8}}yUuHh7|mI}cI6hAG1AdN_b zs-H^jU|c1hY^`6o1J!hrQk|r#K=wn&$|Q&=5N1~Mp7V*@2+yysP4@hlphW;S(mMXv zsH1~pH3jfG!QcwrK6oY#d&Bid3B}OJ}*-tz5%SY3S`wuC3A|tfCMlQvTtota*xv-Iw2W_x+OU7u)b- zl@5I>C>22hlqbgZb(+!Cu2zcIQ=IBDOLg6(dCOOE9TBliu&($bD)BkBc&gbDx(6)e zzqTW3+kmwP?sUrOke~-Zbpjfp1sZ|HR)MbWMWZl4Shqit3z&Ooqj0p@LjY^RZ~uzO zrBxOo6`9~Fn}OY-mXz(T$WiFZuka(md7(ogv1US`@GigJyZk+JLABPd1gE;|{HjQ~1sad{+!y zW6Th1iyAmPi0M7G2{t<375yGn7J$rx<9BbA(CZzoIzKSCHAneB%nGA1>3hK<)zE%Q zGqwy@HYapii=Za8seYfI$T%((E-_Xbl;+RABU_>$mFCixeq}cf%>|A=k{E(q`SVx@kzdl%F~k()tj<}S+n?AvxM2x_*pdl z$S)4eN?7G5G=)jJ0m=8sOLeCdp%u!oN)=d@D(uQoPURkJr54uAO1w_R6-XuUt-9)^ z>Ou0Tl@#Wwwn&L}EAjP9@pUZm^(^uAy7>Aw{ZMZ#h))*87cFMB+jelROZe7R0_z%~ zb8fE^OK$I5)Tv7QS=J#}(lf-(yJ z+>t*dJ;WE{ZDBNXGJh8!frW}W;II1AO22V&`so$*-NAVB?GC!X zGrj|HdjF1ueAt1TZyOBKpBW)#LlRjBrg6A5sd66_rdroL0LJiHdHHQ{Nu#m3!@QZygpw>2CWqUbRW5 zqhCv3Dlev?arfaJL>Uh}>PDzL4Od_S@k0W#l`kJJnP=d)1n668>@9!_MX~~eS_&oH z59v3v0?IBp>Zh_IqFQzAEj=hiKx*^K1P$GR>W;foOk%y6ZE{|`NTZmp&+9LyXPTTCLWmT}c%Q?=pJ#PXd)-0N z%m$+ArD~QwE<|c4%#e!)-dy^cFMV@YFR{5xm)!Znj`_j{s@PN?pC26nw*f@9L@H3s z0#?~HE?+6_XSJccS}PqOu;FaBV8Sk;4VHLm%Ce!~m?fCQ#^oCrYk*q;#GWHt&+dV& z=E|wF)`^@Mk6`3M!AUJl|B`ll%h=5TI)5Jy__jBxl-`Aks)*dsR9~>jgamQRhq46} zEJ6}c(^p8Kylyw>8kWB)NM96pD@F*B;)Q8m))Z=4P1clp1LhSw;2ZNfa}t9t6Jm@s zK#eRwz8<$0Upnc>uYp$ia8}Qs2~pYfMi$|)UPk2?*9t#ShxTfQbm!L!B-8-CHJ{oi zszLlIt+5wo0{5-8O`llxIR-zX`YgdYNj4WhCwq{1apVI`MQYww{SZ0duct(PWz@;O z6aGsRnvrJvNQ{lF1dWeG}ir{be8jGhHMCEZ3w;dugR}vEf>Ywoy?;y}-(KUH!VVUrKC=sAS`! zZA;_KsM*y|{GMZmR(6bQ>a+aGzj|5`-4h?5bx*9^%Ft*qRneG3qV*D6;@s+Ddnk%K zKVs-f3MgJCkYR*p_7SDEQ-?SakO%;SgxdX9QwVXJN;>=KPGwf4{ z`x=1{y?|N3ZzULIj~czyT4=(9HQ8)aFU|#5bNMb`rUOp1Ik%^MP1r8D1m8jCzQ z)(w7nmTwT*)Bt)-mUk3x>eg?6Nl&Kbkk&eH?UFvEh-YL0z05HSwxD&6GhWD5P}hnU zYM5EIb4_lJ4ecsx^N_8SRpFh<;}PRCDS&m5FMDYTzoNcn%5{mxbJ)Xv=tG_ihOaZk zFXlDhLfn{5k}y(6l?3&aCV5SA570;v>$|EyQyu~IK4u_!QbSLnGWqB_aHf5UlUbcn zUSip%2v#YvvMg)7xRPgW_6AA24sy!Oi+A8PYg9(RgoDq zhXXu!VwHd^kc69J@tNPJwz2@!D3{{HX8%>@Tvx%Val0Sgr60@ayg@4z7PSG|LrteBychan??clVM>|6Ud zw?P|fdI8CGLau2?6>3xD0^tT*H}rDE^U(VJO~pF*__z*!i4psegKu)+AC|{Qlq!0b z3l^eva(aqNzKd=1;u{3yLI()MtqnUAJDJ+fC}WGm1K0x$r=oIQ^pnc|+Kzms&K~ZU z3vjNjd@*4@}?6n?nYi`-s{^f$;j9a5Y0Fc_nFo-gX414ydYzZz1 zyRs(paggtN-|3!djzgqpr92YFalRLYRjKAR~V8gR;in&9NJ1oxo z^wAM(L+(mw(NokAVG_I1TG+`P3w#hLZGoN&qgU#B+OYS7C*H;1SPvF26pL#ffCxY{ z==79KPp;+KI{5jdSk3prcCw`@`%CkkhlLCIeh6;P>%zD(+KJ_Y{@fg2{vo6p6?@wcY#RL8!Q^| z2bVY1x4rp0k#(^TedDI$s%~rPU(vX_tFPrJGL0K=2A%n;>ZcxQkcy*PN<9CYdJQ^` zZ}h2}CrdGP+{`KE^A)P@OwX|&_6>=nSt9e7Gg41Mtf?|m<;zdy%Gj+m4$)fwXzZ6M zDT5+q)Gqba+J8-~bC%e~!Q&1JYi6#|QDs~sBdR1fT!X{d`uhV3)`A=v;=W0%aS|wCt z<6R3nqj^A}%GqE+xFF~iJ^%imv)jJFt8w!es7tv}n!tbnFR9eB54Duuoa1xM6|@hmRuNkx zr4Q0pahQ72-$B;PtPNEksxE%MES=K4A=k6hMyqEV>oi|nFLA!Sp160pC#iM4C#em# z50fjeZ^xG+Ul6uus&{=Ku)2Ql5?`FU#k$kWXDoO5z686~8m6CX^fTO01#g5Ka?t8v zyf;JLfG$yt%bL_mP^5Kn6OVJT;Ha7@p;?Ch`dS2shRrChI4!$CjOY^+ZwS4}C@*Th z7`h^|aBC(cZw@}70_%|#y$Ln{(W-pBe@_bXs&`DQxJB89zkecIJd6t;a}AcJ9Ply) zK%8A{6`*+ZuGP36h@g6;)-@4z!CJo{Kxs0w8;HFVU#aUvZ{xc$MFDmzZc{G2GAjE- zXmViDs})_$rX;sEtUb}CrxtwA%K-OeCY4GsaybWOt(0tyY{E7rEg4P}$g5U+?l?;- z9IKzZO>@$s1K&Ix^i4nsupi?+$NB@Z2nX6bl3(MYyHPl+1idbKH zPmMBurYVYPygN#!tN;GUx>ER7yQ27}SuNQar$NW4dpBUi}%Cc%2Vezp||`ytGDz!u)EZE z;F~if!u;)}Q28rGz1)YI^5Hjv36!j{9rYszkZqFHk3zr38l~Gl%NTm6 zmR_jo;trRqScBOO*w-L)tW>{=Idv08ql$ysM_Cms7Z7#bd27(YX}d^|Y|~0mbnfK) zR-Y<&YPAA~xB9@euyPDfmr7YgfnBy{$ptr4cKq})Pf&ZX(u&tH9(#5kpr;7N@j&DN zrv2hU@*G`P9fpQ%5@Sg6pbo(s~+unsb4&u<+a z5bId`tbP{F?<`8l*}1P3Y7yWY^E&j3tQ?;8!zYme z1NsnI8%reKL^_~gR2eQ!ZNRC?qP3`Z_G_3Ue82b3lI7&mSQu%+7AT_1@}}BOVmim(+<-Fbihgj>tkAa z3Y`+szSJmP?&+!MY~qSBXHgD&BLK@O!8`OQ{2ldZ#47)dQN(m3>JX4oMs-8#uoY2~ zw+5f022jCK&GvbABv(w{btB~g9rfNhbuc(Am&k;wcn>0jN}D&YA<7YP7*|2Pu3C`M zEtheAv4=2ssNHIG-*CHqGm4}yde2z^7h*sEyqHoRM^~ej?6SX$*+X+Kf14dZTnf@n zCyZlVo@^wHA&)t6e9V?2*dU2>6p_UtOUUDaIcBI7X4I;j?#vho{bu;TAGX2q*D&#C z!38rHz&A!o(+z_4OBaH*p#(b`Mm%s6ZGJ<=1OvaTtG4I#?YSW#-8a0oasiK-S~4KQlgt_!ywh$MmqFB?I?roG{AN)VLO*`oc%=W z85eoA#n@Ja+(5H+9v05eG|$U4x$kTpv@k}SQFiM^xAL$NZMNZW)`Y*%9zEEm#~y2p zUehLnagxh9$kV#W)3%_H#M+&rZISDhB7^BSrgQEA)canLoxzprbD}GmFrO>qEoJj+ zcwhL6UnLFGGkg#ipv0Ko=qg`!%`^UuNxjE4zUeXVybWp?1)^VYA3wg4R=w3dw|5}y z6V{ku|M>kmq)((E$(t&ps5Twzw~UNgDSuME?AOX_#apcKmu+UQj~54V;xm`{XpS}) z#uF1>ki?WLeD{SMMW4%m$`eWDjg#Ek=Ty$JB9i2g(K)gwKTM-K$^3#e3$sw@0XQra z+rJP?r=!@H{lxxJV0}QZs+2ZZ5mTQjg0F}4RWaunwX8{XiEDgT9jJqJ38swtiUD(F z{pi}tr|Sa(edIDg7Bd>Y736!8B#gf8{|@%e&gfU%5OvMK1rwtG<|sun!2X1>4F0$7 z4$LLfuq4gpGbI^J&~&UHo}^-!QoVXO{P{rO0e|rGKUEC55ilDI{D1zy#r{`{W)EP- zziz}hK(+ZN=UKIQmFP<`mo z0o8(Bct@jtn#&&U_jyqdtU`ugo+q*^e z&T|CP(+-8eAT2ph=+I@m-OE{gnz#UAbSp@rqb!E-ZlHIFh@x|OH1Y13)+YF@O+KLv z=+(@xOW1D-@y7A{w?S?D1Fc7A#n%2dO4u7=M_Y{cj>@(>+1Byy+AEaFRnjpvYJ!!Q$l~*^N0b=|sXJ zH_^1N-$$38=lZ}*yL)crQ|GIi+DE_?PW(1MNr{&C=-_m_8FqMJ;c>AWf5rgeFpBUX zs&QYcFeYu=nWOLOgzizzc)tqpfyJVi7GJE`P1$od{v>O$o6u=D@nkD-kIU9KMK9^3 ztMQ|g*>3zIi}5uTdN*~S3-HSp;U9wmNlqD-noyAr-U8B0A`3q0U{s8aj{+9Gs9(BW@`5is+RfPBi{wsJ){nn2NHcBMAx zHK0%Aw6eHeuu_b3rGo6S0i`D9t6dau(FDtnjdUm-Cd_Eo(2p=-y8c6TxJZ`K!t8u& zZaW`Fq=?Ug@FE_}xaQx?kg4=Z&Dq!253He|v)0kpf5P7#)-((B7jSLI9KLO&VfXWk zkSWcyYW1a74LeHhUdNF{m>DW9G=>H^Scu1x#?@AnEHyff^~FX5r>)GCDpeW{YAWlx z<{BHFMvs+5lqesn)QLz#N0HReBAk8w?DJ&Qr-KH0F(c{)^O-;tH)0w*_1ZQAM4p|U z2KUAWH`k)Rt}X_crHiz_z=~h zbRWTqa3S?+jKyBV*noW-4suZ%S2FW>#%AZoov@uA_w`la-|)$NYdPNr(wIUuZ-vZb zXyCpV9y~IaS9WR23!{oTMU-RRGbjw&2166rO~dfj7+GReO19 z8q~Y6wf92;46USCV>R&3bkD*h9dz+fPaz2fF$wBS+=+nDBxw~E-nTsk^8+e&%lUciV&_^igX~b*uQZ}c#()ozT}$-+Yn(9B53bGTWSVw zg0p_Yu~@8b1G~lsjx&FZ*O%7e)TQLnVQ%QnGDvfWao5?$%^$(uGp$cGmx*Re8XVcA zxxH*s_;A5PkInrHsP}JST#JQ3qc!YP-~uBhM1Z7c$h^W=ghEO3DP9V|;K(Ggw!lqy2!Ix2Sh> zCZ+}D7?EwY(}CYsbB*h1z=bBBxZ+y*;_@#=c*wJvNT#4xeIfzmV2Fp zeW8iH4iB8$W*V4G)V+3KM>~Dd&pT&%AJC04JA$9b$BAkkc5MbFYG5}{9x3EpCk;wy z)n`Ya2XOw=z#MJ?Oz;FMUoX(iXK7^#JJ!qxYan+AUdI1I9JuK>?OhOKszRM04Hv}_ z4JMLQvx*TFmX9D-*D6p4kGKMNj3OS(qSSQde7yQtfXcB$Uwi^T z%Q~MVK1%q#)B&Tqo*_|yLh5g!X-G^{5Zn(PWrbQj43ZTA>hC7}8xJ$pIQU`_RDi*F zxxTNGDC0rB8QPwRq^jMJTf8!Ya5fClP>d!Notdqw(3I+AE+VsuD&6{q&?EPUZS;UX zX|d^{Tlgave7qKin)56}zS_Zp96Q(u_@Lm%m^wE@52XIc6Px}bEe7Z{DgniLEGUQI z2x5gIWmujZpk3&&A&v%&2mN`hZNGUEi~zU~Qi7pfSBH6S(%rme9k7Ke%I%zWn=7==h2y6f*w z3`_6JOOlYjish_uCq50hdPzVR&1z6GT`CyWl+5zda3%Byfln~vwQU zEonFS8!1pG>36oTK{=<2T{-B-cs}1^9yE(grYO0Lj2ct6WodzF1xM&dFy~Bu-{LN` z3#Xic=G$*=J@kt3E!Go{C*EHJ1FOb*mW_zPiW5xB+)O)r9yWB#0L~$KGswE%(qDAT z0!`y`)0Xv$R7^__90$t0f>}i~tZH^R3_kot^U;82VHavr~i8%rJuydiC<)jQX)(@?O{a#2r z1N`Mpb6ZF-1*Wg1B@iylTRzFW&${M)P!waAubC|IZervcAn44sven$bV=IB*u}Ky#_kbqB4D=?5r9XY51u( zP@>JMXOfR?3LYtRZOhr=!a(5Ut7e;8WfOoFSAiUfdT{Uohjp0*`OOqdq?wch9fBot z4a;#?tn4wW1F}3C3S7f=zWjNamt{F-d4+WHM=_tk0LV|3pm9TTJLN-hLw)p$X<3&^ z7PTvBnc5@AFu7&zyZ>qYR*pkE1$8XStAe*z8Xqw?&Qt!jG}_~Qg^odeaRL5X2>FQq zA*GML@N@|(um%3p13_|!z5hb$(o|rJpjXSWA#YKx74l)DZDvn{>C)9Xw3l%Z;#S!O z?b6mcwzn}jsD&@IixP5+2@?^XGP3va_?ULLkQ zB>Nm*fUA;K9GVh2m3286t`LWD;m{%mEuW{CRFE4FGa02sCEe%TkBE0X!f4RrV$LPg z=c+G%aQ*u?07h;+G%=ek>fJGDjY(IE0e?saG>>*hasSt8k(**hDG|>yYhS*>9Q`I8 z+;gY_XPwa~*3D`>(of^nGHA{eIIQOYGw)Qcu$DbT4Ca2Z4CXm{)2#g4l6fgP2|Bbq zZz;YpJ0sVnaiMt^OY0lr67;h{aF?9WlU(goz|yp1Ae0vTVhjmy8`nHgf%q&`Kyt1E zsI-Atky*;6sneIy})AZ7~%cALBKZLP&M& zJ3Um{gIpJsUSCg+veRhiK@)Ha%KBAAznMTMlb@)a7R9-cQ^vXA=n|Zy^Lv7SZI6y( z#8;=v6t+!S59A~M-e+O9UN3Fo(9)6i;v1k}`q&|LU$Vbr8IRxL@2T?Kfptv)`C)r{ z6%D_~g7i9jF(7w^j-l9Lb=Ay#8m1Y$j~5lrooEmi?u%KjTlxiPOMSuLz|f+00IGqI z{dyM}t7;5D_j#;Rae3>!d=+n4FsYLvOU(h54$Em>P^{b^@(-O&(`D#w&T*3MQP!57 zieCRqH9nnzyvj8ijhz#%4nWA6r%lwno{cs`m}~+y3wi}%RzG#xH5Q<2E$j8AxqwDJ zXKAJuv+CEECE3{~(B~6rgG$!HXHnSuJz~2=t>crm)GH`3E^Ao)5ey6-Snq(%vnrHr_}n8&V+*+}#0g0~p`&w(zR}a9{QYP!ARmB+C;{bOVS32{BEHs1IN1gIurY7TsTVBhd*IAiKdAujAi{mcnrDq#1tW*lH;nW)tDeCOrrogqq;NaJtM; zx(Mj@`!unmp0U+z6kbRYM+-S)&C~<}E&;sT0he&FYeGLUu~8t>oVUjr~ORaI5~`Pr8o>-dJJcuWP^pS{#x*=ivi{mEfAJcWs>J4O4MD5x}xM z2E4xh?hf4KlQYv>68PVloYXu9Jzc59@_%R|oXI|`W$@9qF`%mlnXT2MfvitNL6|`H zPB5N=QWjWcA9Gsua?!OZ?>MmmtD#5)#SIIKf@eLyaZQhp-7nzj%4c;U{z5tU(khwm zJa0XRQ_X|Wjk3tRMi9I468%x}1>yUF!w>-u%)F?`sq(kWUz z7xT>gsj`%d-^trOC{k^a(-Pyjfwt)-^u(2p$|Y>1-mnRKXr`NIJhe+eE_ zZNDvLf&yzrC=vpf&^GOp9?8E=j+I(?FnMau&Pze*5i7ZN+lEhtO+o3EF`4zi^Dbtg zZ8}8()aw2~HAP8_u@qm3@M%Rg#*AH$qAvo@CIRepDxb8&bj(`jboD1J^d*$eo~hHakd5 zpsB6p7A^`k+lj1lV(5iw%?AW>wX`mp&Sgyyc|P}qw&yfHRT=WCa)pFtj+Xpyd;LeP z#QaKuG7{pp?lWObQJOg~C=#!36TvH{J)@Sv~iPX5&t{522ROv2CWZmWE%rC7LpX+H*YUMOB~m zK-03k;uHL_+O^9S3&G3gRV+!Ft0vfX9k?tPCM*}gtR{?DHZ+@blPYlAJDq-T3usmg zD5t50G|-eDPymYuDXYfRR`F{>B~2EnD5jfGh08Pj(fKE4yY=WJGgDk9_A|`fVm0zi zs1&SRA@WTnRDsm;5g{la^ zCTQFv`3iRF5}Ug1${jZg!$8^ON#Q-a^ew0Gqb}eVQ0a;)aoMYV9A-6a$jC1N3O*7o$#u>BwHdr}{ zNKK{$+gbIx5SQ^owazkQ`4d%BhZYGpN6D*125obx+Nn9Y%-f%q>(YIo^HTE|>1rOy zl`spPOw$cdtrw@ocGhlUMA)VI!fV$ZsfE#^)nfZ5iPx76*LULTSbd+6`W8jt6NYfL zB!q?w_##sR(itIT&FJtWp*M4ZKO4YpasBspK~Yx$NmpS}-Uz5($fzHn){XIx9qCZ+ zz+4{CUF`r&O&c@+fF5X#17`R1x?tgd((YVoPl32I_4XRRP;kfU9^8G?s@}u6AwYGD z9y}^BXI(6r*QzXYOMQyBnxC4@$~9fjhADfzY2)!ja+7rK@);`Ap&BmoCnf=KBjM*y z?r%5z=}_hke>mWVDw8zdgzTBI3yhK6$pKG#{|$01}tVwjQ)GJ2)!v&N&XS1jKFY)I*DG!_)jp?m1xVbk6U6M$KxMwa}b&_w_wce9W z14}KkPx=_%=v?}VapaViTh=auUrtPpm|QwAJhuTi0V?cVDPEPB$E9n}SZb zYmXQ-XDM;5?ok`uv&$VB~dQZH(WFv+oI77TFpkEh&d-0>5gtPwVO{L3q zbc&JHY$4(z@6e9=tPK2w9p1H|qipJ8RC>`hGgrn)eI`7Z2DFbdKb)d}Oj+;90r4ri?!EUa=Ff0kGnr6paWvzXcTr{{vGS)7-mb9sRva9fJW zgc{}6gl_3r@g6sy%D=xsA1+0b^|frRPS~dBblvKC984vg&_#?Q?-i#MLY!Q!0MY(V zpmX!EoJ)M|?571+>{}r70AWN0uQ&oXtT=|dCd(BY`~LCh2+iJ_PB1YI-cEOP!3RV3 zo+WcauZ-y(oaVG>d2+XSj}d*%y!?+0_!HiXIMTFtW$f7m5Hf!*!%{CK3?0LaL65<=dh{YNuQT0f0Bjssc~Ij4zPw3!U&cSoD6b@oU!z zuQSZ-T+tC-T&jRV*sP2vcn+8}zz-YOu_ygXWN{n6_kiB#STq^%Aek)_d&k(-i`Qm(;1;p%QIoFM_E%m*cC|S!+-iph_;{599K8W@(zh=@|{} zv@Pwt*oWcfxv6?7!38kXi*8VDDp$7T9V(jf?J_A1>FvD2IZY6Yoa92d^b&I=-=JZf zKiuVR{kcj{@1=d3LuH)_6~k~SsZl>BuS_&$0rn{Iw*bFpA}`BzISl%9|7y}Wk3^X!>MytpkON64ubR}7z4?40{QzVn(W0lH~&IQ>+{K| z&27fP;2Scr3@PS51@n}sh456osoj&&ywHwDhAWwsCQPUvu;(Lx!V{jKDx zcm6lEphO=bq<_Zow)w~`(8J$yA)=*p+}@p@z^61QdHc!xPhrr$*({yr z{gRO}EA0zQ^*-S(E6ojw+Y2z#4fy+p8l$v3%NTOOtn%JP6t!wlb?_7+FIMsIv|a*l z3X8M6yo4D~c|jgiwJCB4w{(nUX@ED!a{f`FSUCIWRStiw9H~ohRZ-2UxS|J?AuVAhG5{#SUIqNHHAL=XS7?K-0fXeE~6Z%dzF&q^~h3QCtRVQolQ z4ir&HaDP%-FeRQ%?m%_l6t5ZYz6TL794DA9RDcBCAo{R#?9J=Hm~ z>U)j%mJE8@bbLyPuA-KSc}x50VE$5L0zYz4U2}*gN-UuT?a_A+vSSY9wyOb0nD=;s z?=G0E4a3#)pDYb4QHM`|{5q6JuzUU`_|qBQdFKt}_QL|EVCWkN*XzRXV47kYTA$vU zVB3A|RN^49j0Gt9f>b3T1}xB6#(>;;P~fWFE4Q=oYb+vlQ05OF#26gXV9)L3P<>f} z#U86BD5^ZOJ!oh^6T4Y{a3lcKB_=EM_CRR>%{ED**}#~5cH?uk*AZtTct&R~T=1Jj zxW`BHum-Xy*S5z}0x^23u zlGQ*#^$6LbtGlj!PqfDShc=L}<9%OBoDz>UzxiLPKNc_9ys6p320bg9?W8HAET zmceask48oe#EsW^U0EkoWW*N`l$U4qzsC}PsWm7aLDa-g&o=4~3_T;mg+IRk{6`ID z8^OE~|5Gh6{~z{||DIh_{l9Ba*uuct&P?<_f&c$meCi(hO3ygI-doHPOKXdzCC$y^ z0a0@9QvamHgKN~pme9c`rfxFg3++&F0D-W^c!dZXw)?p@+y zBW{zKyoYN0D*fdn*=zHDW9>a0aO-)?g_FAX>G%nt=1V>nYy4V|$^*a6gS=z%_;A|z z7If`P-l;o!vCzm(I9_wS$Le^ix$-?7xaDzQ4dQdZ;}(DrV|{Xlskyzpg?WJ|7cRe= zSIVf)oP;fpV5musffiJOwIfH2d~%+k;E?P34C)!Rh_Lbk$Na4+$bn5)D*-?HQF3k zl?ZLS;9|^iU@3?LZx@ZRg){Sj7y-{UzA3B~lNnj`kTyWk!G0eV zJ}sd8Pghb8*x*izF<0+VrqLx&SyiHB8ECWIso-3#_)qKzHpZ`dxd77SEj)E{kl*W~ za4&wxn22I>V38J#}8fp1$NzN8WKPlZ;DVCO~OWw#p zf$LczhkW=~QJ042oS5HaXNB#XkBLg zlaV?iRFOKu!jUYJ&TTK`YQT>v(GVfL2e*+vux)|=^q50@k-MNmj)B^=`g!}7n-mrv zO5{7a+*kuw??Vr_DocK_v*FG{eEI*W17QI+&R8q%e_bovq0p+_@oy37jR|?@?Kth# zgitk9C<%~2wv$IUHth?k%56c`!Lg$}z^BbU1>;Xio`u(fNQ{^5br-Tvq(IUdPh+f? zfK?`EiYx=KzegrY5Hle(>-*Ldnkr#2TZ%>welH1>o{5{Qr|#DXPcvL>GOJCh*ve}X z11ru_Q@dONHePG*XBcnB2=g9|#0juR^_X zODmkAXVT0?Nz0$n;!x>@_K>^>GGq+`zmG0+tr=59QiGi&rAjBLJ$h6ZUq_t2>14}s zyNgATxV07)m^5IL>E16QF)K975|WOs2NqopQ7h23B+3e7Tklm6W#=u6LSl2XpgA{- zkPPE6M5J75-AYxvD#?->TFvyL*^5Vlm8vxC(xl9PE8zyBKWw0%hkGkh*~f<9?nmMv zyG(L)a?m1Pjg`bj?>8fHgiQ)Zh8F)}f1Ym88N>7&SHEKRF`%d@Oy4r0h;q`CE-P%* zfhoT+r!f_^{Em3Sbpko-b3Ic|l!1X0Oa3?CDtzKD9B~VA1upvV3vx(!Z4}Z zQ)wHK_Ins*?kP>H3q`1Dvt}vG@i5Z&*@Z=s3JXdXnXau8B`CP!hGu7UzzpIXM!8(h zy%k0iUD#NPu82%cI4prHXAo|cIkFUbA%l^Nr!!#3M29U{Duq`%CRa{zusIc+7=mQMaM?Kz`%TTYcruJ+ zbqObSWzS#|auBs|^5Hkt#&Fm;R{T(jbZAgwmACLlIoHWYi*PzwAInMikQ!u+X(Y{qwd?vZLKi zRO9mV&|i{d2Xn&y0TZn~Wj`>cv>F5zJ>%z*WO_U<`3VRqugI!2@kbs4D&8blfbq~C zx}lnZg$3hkXe{MVDxc`e@wfJC>ffHo>#t@b5t_l~SQ0F26_~MxECv@+OGN!`gEvCs z)mMC{KnWdsJYT@F0ft=S#+IDJg7seH;lFgXeYf*VI&@QgnZ zhcefhea#5fo^-1+YHi(7?~9CTOj#+^%>V50xS--%9V1&%-%OnL;=mMQvL{&W$+e|+ zwxe3MAd~K}RPdJt&HYQ{Q|t`g`{>|gGR%e zsTc-q`eC(y;}uLjcF}UE+dZ;B=MIU(tM+g^*n~gGOt9?$?v`vSO|N4(4`g;~IjLdk-C-H6lh#6)f|BpEi+GXxkvXYZN7uHW}pu(oY08!~;muH8g!UdgN!188>fy|-9 z-=a{uX^zCb5?iZU9hsN>%aqacaBUib_Db6WY*H&e2}|IRP_3D+PP9A#1PcB=RDgNld2e&KeS) z@@GTjWe2vrgdS%hok+fueW_ret}%Fxt!VH^0`eQ{$`Z7CVRcfads}J8w9=RMchk{u zwMO4!#TLdl6DEIYO=QzDK2lvKecZr*&fYk^;oRKR{5=l&Kc(7;{?A{336Tlt+W%9nzEa8D8i5~)8!(};#Z!&Ca0jrF zqG1H3G#W@>YLllY5DI)cRO2J|IA!Wm`2tbV9$b)uE?Im`WM zDs%Po?s4Auha=aN9?G&&ZNxc-1csGKOX;o(ig}CWPL*$+FNEM*s6&Ck{erFg2G2p)!hI-XVU%Hy+=^o&R~&a$!Fj_*?y$1^$?7^6 zUeu}+)^4)}4v=39C-&8Yr|MHB-UHXN>XOO$UY2p@qFQ*er9voRt_&iS1s&RYZo_+@ z@d{kBI@t7 zl01_=95WIsi!_Hbpyye-8pAyR91NF%n-6cMG+lXG^VJP>HTO-#*?dc`cU8k6Ev+1{ zD-gyBXjxHohW?~;vfCgD?M$bRV(q9plH4L0^GHunh10BKPTr<9j-#(G7i@^)V%l`} zLXooj?cz%?^e|rR3(DPxLPj)Da!y?5vj=rx0ml{uUpM-&hbXNee)gub76kpzTgTJs z&b#4F5peXk+8O4;ZYe*IO~JIu*>vHg*i7|5U{5p<(}+cc#?X)fM=3tSS_I=Z=#=pW zGFwEedqeI-Ix67tObSd!CI!4bC0&^kQ=$vf5~cdckz#F3GTCD1&0K?MwsvGQRQ%J4 zV!IScBPb!+z1UhrS|sWD+J>W5#f;nk1DR1rIFuN_A+yjw)d~OKO_lTSO;yoE*Us>t z3WNW4{>wPU1r`4Rp)(cNt>*dQxYN@$mvb#OOu(BJG{n~Y02=r3!N3Xdses?$lmcAV z*d*H$>zghd;j#xI@o-*#@IcU?6A>#b2jZDKFEJWVMMN8We}3H}_7H9~%l9#3B5Sd( zLu0bqj`vwYrlVZZC1gnuKQab+RC*1_nFML~)~v)ybcnxW!*?HM`fw$xoZRn(49|5$ zX8?OrA%-CV+iY3Z1#4I=Z|EL zY;sJ`|5keve3XBhQ|myXcx*V)TrnbZmw+t%Rlsl(mXfQ?SxFbO7taa8`c-&?UL`^j zP@omm2q}h+f)LLuW#Gc)jttU{T~te}BaweN2Xxm9j%x#IpWb&u-G>F6&3qSJ+ zoDHRo10cVbPR1FHaOdfPgaKVgIx~?GTT5wXV)W=CZiO$F2H#(pl|eN8i?Vao!EThH zZZOmO_piE}pO=LbuP`u|Q*b^ENh5QPJ!fREaIS7XcUN1g2PTKz`8UY}Q)Zo{ez54X zLvUOK48`Luak1Z8-i`vtHq7Hyda)LXH^O6WLZ2!lRdUNHtCe#b|1(A~*}9N&{jIpD z^Z&OLBV}su@UKD)5&b{x=vxey7LXt5OQgKqTwZvSJgjU0VJidA$h^le(H6~xhnhDHSQ0mnk-@7B54D<_(3Ei=?UGf9zS1U zK;a-M2ipEQmVUEDO4ge~^I+TZL(tgGt$NpTLsdhxOyG`LB#JfCV8BuXhY>lN=Yv{# zeX;D9s^4g(62vt7M%qBl9apg=zaFu#7G3ZfH{^>PC7^!SOeG@ph7R}3#Ta!a`xIhJ zFdz?vP1V6zZN1p;gfN!2ivAI3#&Jnk)F>Xi{g5jg3JkgOT<(br1TdgZL2IswKn5g+ zELY2?c}xHhlu=yAQH6dl`@+izF}p0Q(l7Kf(?0c$&h0KW3_9Hg;gV>^&jV74-;0&V z`WPONYq`&4TexlT*f^Sd2iG}~sgXwE)Lkpd6{C#LeZu_RnsEhWset=Q0`e$#(kN<| zS8CDaqr5fqobWs7WFgD#KIpU|t~nI`AoqKF(=ALtd~PH4FINzEkuv*Ef=xq)c(iu3 zLKp2Ok6`M+P$2alqD@l`D>wyr`TiJ>?Y~0c6H8H6US51$ssH?lJx) zfUlgS@_HbuzLiBq1yHMSy6*X&Wxt%Y?cL=GN*5UdD}A$!?_-OO$m2psu0IxR_F|p` z{wk*?^?m~uJ!mVk!UaEG!N;9=D>Y;vG$qH@R^Qs$+>H@cVL??{ePL}`T@l1f*B})2 zkWoeK$e1gPot_@*8uXT9XoR)t;Phy)^!tX!CZ01K3TLr<91pmX%@mVxgNdcC6tI75 z7B(&juU^m1PPMs}4K*>&euNQ9AAU1p9VOa4)q=xvH7Y56_Q63T9OtYFzCpos6C5=E zpp)Gw71x!(9P>OV6`E5d48I_0m)#1>yfFQ>PD74*5G!kcYBVsZ1gqbnp@#Bk^Q3ir z#T63&P?(*l6polBC@Q^EPPb)ze8w?d6h!!Cy{-}~8k0rvk8-!)1cT(VflfS4dQ^gR zv@4e`TcCn6o`*c8`EZ0XP1&YfV}@d0JH*-yjlN7T7YbU?wGna%s#5-WeQm~}IBUaO zX$0S(7VkR*%B?~#CDo{!3fzD>Fr}XQASN(=z_;)=M*oR-tL|D& zCaQ$q#T9fAvq14~K}Vg+ofan) zgBIF~^dms4Gl~msERAs*HXJItvY#VpQJUp&(`-qe1R6R$P1{IhhI4WP0pb2@nyIga z&9fP$6-O0s(|T{#uA*oHgr4a?f^eAf0}UuM%kbuL^$5i0`8gwr2-UIKfZxy39Olj( z6E{!tl*!R%N`nok-DXvR{^ZGOGml>OpqHVstYk2~B4$mSa0DA$e<00eJODSw^X{a^ zw-wqeU1#>K6CBGkW{Fzj@T?umCkM|_OCQMNo+M4p$OS&5#&Y3B^YH@n{J;evPsLw@ z)(`L+cfjmJ+v0a5%p?~QTmtlI$0Ra8y1IfFDd-M*4|sr61uo(B z2VntzzpJHM*={oJ-EHNxR_vf7x{Yn z99R9JTv436)8Ut|Cbj=FX^t&893r*jfrh*#!q60gp)e&NNhlN_{sEe|dq~d0M)Mg< zu=)jX*|8&sp+dRkT!n>ut3CjG;~HdW2Fz*sbOyVh#jhReuy3F^Y#r(rS`-zE5xO5G z8gwb@rs*Y0JXWj!)XqNLJxEKmwosIp0*Pf>HNwg%k70TqxkvVM z$;Ai0(QviUE}YK9ojVliSL0+(L#FRCa(Ykz%e!&$BCE$p=qg~lIY*c7a~i=3ryGJH zGDVTHK~3C1Ss28U62f^{Sb0flOVGLahMX-TC56>)QG9W*)X$E~dmrCLbOjYo8!gq7hKm@ywt0jNCTGJ01W0Ukp<1sb(%7*-h^3>J zXM2m(%LV6)B-2JCCqdVDIqTNo-oHm*;je|BOKTk4T*W7AKV#HE!(;Yk1QRAD@JG_~ zSpCs4%BftLHO52o5_$YhK~vt4j<5*RbFg;6?F<%YRBf>A>(Ua)%Wm+?W@sYe-a~Fm zMLiEv14pXO2y5W?uI1x&EO14iYS>^%o?<@^3$w2A3lm{tcmnDIkXBJ$#-Qi(B6|f_9#t@WelELl9 z(oty2`Vn)=f%j`T<3(5q_p7Zu(ZM_m3#994nwx6miXn&>BxC2klPGv*71&~-kBd&X zhUk0ocX)=%$LC@Qz4>#9M|w~?t~J@6?C|v4X=;{UdX@EcF+pMf;TjYhjrNeR`jR}_ z?nrYbM>0icF-l=jij(3+Vc<&Vh4f#KR6rbIr6@mIgq$EP)+6F#Q+ue11ckwIa{=1s z_un1-gB*uoP{f7w7SMg3Iflpi_@U##`4z&I`MiBP2P6VPsp(H9QIM)qd&D|*E~Y*0 z=g}d$sL|bk2qhWXpylmaW$+RC3VWWG@xT4;5 zIj1(|e=VOoi-`!P3RViQmL38dqCJ5Y?aZ5d13dUM%Gxk!(-gz&6vPzfx z`N;+wbAVpoVTEFs;*bi_DiPKDe^k`j{NRzdzVivJ|J9CU|K5)N zPyGBhkXp>z%FtEc+EVWyIp;U7R-ETU;{N8{5aZ?i{0Tup0c>%Q8PuuB`8w_wW>)UZkb7I znXYIzC@3An$`oxmW|l5jmm!jTgXK4Ri~jF4{8pmG2wZxiA;xv6%GMrasN*|@(8s!8 zaI+}1E(NEPpfJx(u0)S*MHZ3HhM~F!+#!ci4lY!HiI5*L!%etu=DrBmnLV_0DNPCl zW3C-a2uL>s(}|eCbBz**bWnLKYuWWKXd0x5k)Qa_1k9R9xAL@r^-x0+>TXpbXe>k1 za+N5JDW$_$&INuEPE7Bp;^=ef{OooEWeXRN*$$Iex1LscnA{{sHp>It6X`9{z=*I+ zRAy>@f{4*KD+3H!DQdGZ{fdCoQWblxzRV!+-S87LmFaa{Rbfjay0UEa{de6(#wX?m zDLjm|P~^O*C2Ae{OEinHL$egfn#_o^+o!nFeRL}q37qBZ${ob|o?3vff;e{VTx&?y z;{xn{T9a+&g@JE#Dx3g)FN?;a%@al^ z91{hxx+l$1zaS1Jlq)dETZVs8yKfaCg6Db(7kqL>hxIu<1i_Ayi*Riu%8Y8n)=mpT zWU(_}i(ZNNwbST_-Ub!08nwV@8ZWW#&RYpAn@SCSo|B0qIeqzg-(QOXnTX-J$kmA9=7g>~vgH>W_J{1v6idjDC64$SX|f(ofYXvZ zJk{Wg^sh9a2ej@k>D#rIg8X}m{ok%tk9XCLqDTK zq|YVJq6l`)av8|AWl^IUxy>PS_Q!XD!MJSWOBNohZ?GTuMojDHBXlO>3tsvJ55L1V zM{x?Ct`N}4dKC8y-jStOQTkQ&e?u?h;$dyhn*z%K!R=?i5j1X=mTOF7c$GT5b*Oqk z_)GBRq^lkW!d($4T1>>>G9<)0o{1ykw%4JP;Mk_uA>72 z*7J;v^irUEn{om2V>FED3#>4>atlfauid}o$3e(0-TQkG))|UA-I6jQ33>Jmk?0F^ zKTNT)k zUdqgun6{vJ^c6WyMIMcf;Gw%Pl#NVfXa0kew)lq#SW@m(f9_*ucw#nhYqnGLoel$L1dm~3802HOVsw%e#BXpHTJ5a|x+ta7PTkJl~l%#8RM_*L~hyiG&7 zi~p60zaxz6l9ucdX7_?*MAP&EjeV&~pJr4=6!~7f)NzB4IzxQcU+Ac$@_moJt8711=hDcrv8VE{_nK(e+l*fN=u2vt?V6itsG2s z9ZapQgkAIvZT>p^vz8>UE&1~s1Ll{f7pW&b-74_I8qOjJ0g2GY{ifzFc;Tt?mpQp$ zXgB|?%<{u|1NbaCnR+570-NmFaG%~_f8OA{U6B^r{-Qd}zrNIsf z2)oyZo0kYmKyUGh z(iwj0MO8#|9MQ$N@a3Os!0>j-j!+YheaZJb55 z!d!O&0*Q3(QG_2XAfTTgLQFuf13sRR*(Y(=7BP6hP3RqIaRvC7E16?|IF(g#IM9{OWfK)(%IM8KSt@`7-WYqJT1-l!r zs_1c&@4sYJAC$kpY&1XIl3sg)?Z9+k_Oap#tV9;#&EXs51lHh=Gt@Dt2*l)q+GbUw z3WN}#3gC#q8NsQ*p{7~|&qV!%WUmC68*K}#a7>I2e(fbjPfpd^*-vM{0oMiF-Xq;M z3f~6bmFF7Th#qh0JIgW{a~5>@DeJgn%7r*kkIxl+O%J3!^lbRSCtyxtD)dXCN zpxjpd%q0+M1R0^T6w+6>(a?7ZT?SH!z{-cQ(>gfdqEa4kZcN2Pv&0!~;}H86{Q2Zc zi6(beM%+jlIPa5#!UiMTDY0*Puq@^P#fH#73zP4|X-zh_8z^aKxChkpIqm8cDU}IV zV(;w47po$P0bOl&WRfE3D1!b`Nn$zChep!IV^kQaW-lcM@j)-~G;r9e;`S!`&x^@CqwO z0O2;=ZwuG!;L;f~Mi^B`pQe04*O9Y<`W0K#eB{iKJYPqUTvI>D1^%kgU~X>{h5D!^ zQjfe5{$BD$iBksQ6@`lY@soD+rO+=KeVm_J-wb$>4%<<>waZo;F?BarFScjH8Hx0ew*&-*uXqR%Sn)#ovvonthK?giTK%k*>gu zJ#tgt(I0uuOb6|)PQ@nbQuPL+st&eW;l@yk?1foJ`36Hr^#*gJc!z0f#=vAl62dEd zTfD__yiRY^x+cpNc=^U1-J0SBF#UsYEAEyQT$IPKvVM=3@&&Sr(go8y@s<_%dgpp! zdR<6VM7$TnYJn|%F+HG4V@Z}ab9s)*!oRV&GqNq)thf0Fgiuq8z(~qPvzm3T=1&{T ze2HsAxNz^$JHdSVZfko-=8lPoNT07*=a?I%4t{(s-tH}m&@>2JB66)gVyH%p(9uIj z;`|sP{YeUPhG%5OeOVDj)>tT&IIM7-CbXFwK%J+%eTi4YtCQ0^!(>7q1oXV$u`v4V zX!@GS;t7+m{f_tQS_Ek)!39tvpHD_c0l=J4nhxB?pwgW zGuL>YsbVi&@;G=Jl-j|0#A3t^6A_=7+WNao2tR50VYCEu9;sDtV%|?@1&&eS2jH=a zI2)6b^0$8Qs>tuugaI#BN9JuQW&dt?9p9?!>VvrUCRoVC8#RPp{^f3k%K~Yq8IE zTOTPJG8IQS>j*_HBD#E&irM05WD#FWKdn|iy|VAn>8HbWDtQP-V%z6v0z^tLJjB6W zPmN?O2S#+gy6KQy@cu(PnEdHtWLe8(-eGtqi#W1^aZ0_M4#W_L>v z9EXzBwFsw4wrjIorMC<3R{K zKmx5=)}CJh>e=hy4V~y|7aH8npKQ4VdaHtjOempVto4Iir)*`U12qs8~m2mx&a{Y}39RAr&PE1AGen8rs0T1ncfE#hAiV>T*kd3e~_djS%T8x2yMAb*MHQAIdto+G%&-yg&yAzxP}t-Yxzx6F;q=Jd1{wiJf+*n7uIlty z_R2+;H9QxJ219 zwajPq9t!}=%+j#QTmdc~V?)<^=Xx|?8gpS`WXa&Lb?)zcw`XnAQSy^0UR zTZ0n@FYF~BT}>N$A5S&%ToD>lvG#-#y)6oJ{rSZj-M(xc>M6wWtiAp#&aNqL7<%cH#AGq#exEC;8%!khmOW!u!s@})}i&;|+xp}2= zq$PeAYC$9b|1_HzjPwK6<-<>Kw^Lw?dwzc(3CWxC78pGA034{6;J)j!6y`AjJ={~d z#0R_}zsxxCV09-VP#*lX)<}Jc*`{1dbk!j4w5{DZp$MJaSO}^6M$qkjK_zmh-z)hg z4M@o(0UBT07dQ{>wD>zKs0-Yiy|>XN-q*Ej`kg~G$(=Q-GpE2XxtYUJX=r~~7Zl$S z|4N;|%F4V+zKiie|0@b-|NBQMWv%;-z5jjc;U9m*t&FVyS%Ojr_rN-I{KI=G!Ko4H zSV6UV#~v3+UD=QXJv3BDTtkdoN4=`XQv>ZgdnKk(ADp87>VpP`56=CQ+SY`Kj0Btn zT%26SLOcl0ewBy`9GobyNnBH4P5={3I-bOo?9`pHzJ1OtQ29^Uw(Rz8*K_A{mvi*P z-n*;^U=KqWY94xV=ShD}g@^%K;%)?#?8r^Q_fE3`#g`zzdK|7xVfY|qF2ehI1}@V6 zd!3Aa*Iv(DFk25r6R+`b)LT{tkM;2Dopzj#f*p6AiGgR}TSHo%URZ;dT)%GRo3doz z>e12d(VJ(65C0yof}LT%r)Y+cct7u?_+`VFP(N0ohHR8QE|H?KDR10OR5x6yce;2nr~EpcJ803M<8nl8?b4JGOkVT>W2Nr1dxs6l4m zX71-$CJSLK)4u3I2Ui<&#&2I}``}qhO2wSP*-H_s0S5($+qLi~HCWE$Lq!EQ_XgfN zI{U~&8nLH9M95@>4@DBZ=B1nPIO+hwM#b)>tbS42sqHf-#Er_^7S>~bK=oLwO^DRK-y~2J!`tk0*=@zkU)|!F^Opz2ui)#T zT8(v-bkyFvGZ(tpq;F1a>jd+6=)=D@LJc~y^9c>yp>gfONSD$1J@IrSoM)>FMr8-)_2AgMwLqXgRoRXkkYEO`z2R_-P%6>~Bb zIa^;}2W-}T)gA+wL# zdyVw^db+H$#TO}n?FNOKb<}X992K#MUp+Vtf==Y%%hvw1kwT-2g{0t#k}YY099F{W ziKHM1DGTXUvZahFX^{@fXWPT?mU#T_oy8IbraMIBw9hunL`jCWR8YFW2Y{Yb!saW= zwNNsrpi!jv15~*!fkx4kUHd8*nWD0QQb|Kt8b_mY4#SLO!N8?Klt82!XLpYS&akk8 z7mMjFewS@{ck!v78D<`U(I}t+hY@FSuU2J#MqM^(LBjzrc0up9V9C;igH{h9>ehg* zB(QM9OkVIV5hbB+oME5FOx`w_>yJcYRbC@SWk3CrZ&6{mX#5b$QbR(2G`HL>`s}&x z?CvGQh97LX3mPm(Tj=vMXPapuOX3pbsh+ewM3mqjq1~;~YzKuFyEvOO%Zv!Dr9$iK z%0(_Uh2`KURca<7 z8ZEIr@L!nS)QuXLAFBWjt-vm8l%_ z;4%_P_bm0QS{(x^UA-R8$ln|MdxdE1nJX2B{FN$`rN_3u{J#Is@^{lDo>5Z+m&^G& z%~T`X94W?mD!l^FMCZe`fS{0EWR0k#;9X*w@qBh$;<|>Af)6e;J>2mr5v>s#mPXf* zeD~KuB`1MPCGODj?|mVT?JRXXuNk+j1>XH4jiG#2`w9=z2F;Jpv1XVE( zF*Po846HISPUHQa98Pf8b32*j=%VHYYm=_THXAQsx0dZ7tr0F(!{SqltS?@$n zPKn@-1A@C*HM(njD2^&e45;g1y~#Bi(!=tM zflY=HI$zaW#<$9qGICLsB15cj=_3WM5R(g_w`6fs^pkmXZ7OxfY@?yP#Q=lhtSN5Q zO1(%Fnx?l%^2CD$zby)bAZyY7r0!;Ou&5537<&|#4kIYQ?$rvlq3bXuE-jf2NVl`g z6iT4D%o_Z(HoH7qo(!m6Vsexp=_}o-O@D&$hj8lF!i}x^0^q4MU>#e1k%1gu;U|bq zfIPZdrG1$tEs)5+q;Iz>${xeTnQd8+2Zs?MKc7eB1ktN~KqcLuXvA6&AF~vR*0syR z(f_5~^~0%%^Hx|?w0hTJ-0yO11ty1r7P()~Sf zYs~;t3^c0Xl6IY;bt83FF`BDG8Qz4x3E0{0GHCte2PrwPK>~NY6}Nmp11)yRddVTF-cOGX4r-+}@qopkP>6cxBqrhQDut^d8{) zN^y3+%b32W^8Pf9@dk4JVlUpk1C{B&thUP*`4Z=G+?92yXrTKgitpv8*WqjTfu#I` z{*{pH)e;E7L*7xbxcRZhW$p;uy=++dy#)ATDEnT+klaEn4*x0r`tVkfZHSZ#otZ() zX6jWo_cvT2mn(?;iE(N|e1|;9E|2MDS6Cna#I0+#(Cij`NtbCq*%NHO0a{@`*?NCV z7b;zL@yC72X>zK!_QyGoza6SfKPlOMJUw8tO2*Y$d7!Qk;~2&q6M3V|)M@SaW*lgMTP|pkamRDsd9=aed%C9;41rs#siBARq`ZY8BhMZk^$<0MUtx}8uIjeQK zu!Mj&kSKxlJ`B;U;@ORZD!Xh^>BMxybj3py;|e=Yhxrg{)9MuBa$PNUgG7vB-XL4$ zqOa790{%{mNjlL70IFh4TlT?~G*(^I)C?_I?VIqDZOPqgPb`3=$LJ^nW6 z;Zqqd5#0Xell_b_Uf+5L)T!A{mq?yK))Ta?JlTEhwrFZju|g&x`%{4NvT;kwLcKWE z;Yt~P6&hT`!BYHK$C$0{iwn(-M(HGneaR(s(RES1*j zu+C2e6Uo`}$VetuXN`KxG~|?_X!fblXMChNWA!VjT?x5h)TZeOn5dcDdLd&sGhda(#1*U2XVPlPCM0E+`SH_a~3EbZtb8i+1hY32& ze$bldo|x*m?q{F*D@0h>G zZd!;m*Sp8tQ?f)Z7u zImoQ|(bm7mHNHVS>$onR(SJ0yFjZgm?q3|y3~P6XRjc2VZx}dI(+rfNd;;HXe-yLT zNW6w0B4<#Mef;_hPOll}(4D~i_%VX_?=`Le=8ZD_J)Hg*r|ln<^#3ArG%8A4f48tb z)7fxS_$1eYKqSbiRW(90eO9J15-BD zz#G63K&f1fot`>b89AS#v$wkdU3{cbT`Stu`Yr1>=*KsIEXkZa(49PqH65?(5v{eG_b38<|*d2Hxv-%$n3QtPO#1y1{CVZ{WmGSbxpN~_P}80 zdk0W2u~tDN6HrX2P?MM{b9@|b9hj$N+uX6|pkt`=3ES-FEP z^fL8Y;gdCsx zs%9%ArQ38*$$5lJ9|-Jn0w3pPY8rIyk_H#ifkGiqQJs9QRwoI{B2B91Z~ zE7O_I96emyT%0VHUxOktbCY$lL> zt05-l&3xzTGS$d*PNK#Hg5I-pMM?Z1GZHTZSGUpEXA(Hwun8lmE}E#5oaHBvk1UFjhy{H_#Lng+qG<&4%8eLAeqc7K%9kB2a6wGyhu%Pf_9x zlw&mEO{VS6TU`OJxsMlx0?aEx<{>LB!mj zEpgDeX6(Dra?eN;IgnSkotv(=JTP#^k1Iv{Mn9vZR=j$#nn+rMibUfDghe=cH9Lyq z6}loF`xE3oUJ$LQRqPsp?2yWg#$ z*Me>Dq;ht&#CLB$>}YnpSXw>V*e8QJ-;X(ew1B$17LDw@qgn96c8~YFuco}WyyC!K z9|r>Jcw~2jwz~HCgSsB#!{QjVn76(HOk>^c!NYoy?MR9uxY;q4MuRgwmZs)vv9K?E zuUTf#>w)rKMv5!N zrxtD7ON~ehFH!<*XEm7CO=r%ejfgO?cY8ijAgAY>FqyS*6Iw)7;j14raSGAO-b$V@ z`3!t;%2U~#S^#;g17~hjpCop*kYOoU5Fn}b7enKnO-me=Qusv-moZT_Ss=0{1`CFsTtS$*|7~6!rzXD<`NQk8~ zGbQ%;Tgq*^^yg)6D7-GF)BMUIe6}(NEpy1EPPyrfIm;~YJi2BQcbE#e)YQ~Cd zyyd-vwb#*zG>Y{#C07f5!oqw_#{i@CAmZ}@8N{(+t$81*k#X#ErRuwFESi4`NDa>np-PZ+Aq0N`C!fMau96uo6M47$A3$y{tzwWV6p5ZxPg{ zFwD0oGRIr$R_V=mk?N(WKsg}`O+|5tq`4%3Y|}G_$%0=+iF|k*d|$R+M+?nDQOCXC z8HVuk8%E~xB?ab)HnAq+K-%Q)K=^Lhn{(0FTpTo5tk;xU({z9r%zIs8$BgOd{DsAU7EGDSz_z@HX>m5J1L0?`k+w2f`_{9NQUF81{xwDi_7Ozx!RMy6#n5pe_2p)wqoqoS5cr3`Wn&w%Q@ z{*R(k7cgb6>vDr)uX`z=0_BO5wzs82{BoD(1md3myzLu0DmsKO($A)YhdV+N< za#Fq0*a2kD0J`4snwqZt^`ntEGuJR$ZJNy%2Zyfp&7POB+^Kakd~; z-#u-tH-poBiovdRUe>OCX?I{zXnLNe-U8MssJCPA_T3yH~BXb4| z`WS*gJsO#Jt;qm<<|r+)+AU_-mHV`2S{-Mz?MnTw5<_d4lXa9Z0PNWmF){N+WYXe)ju-4D0v&N0 zKt<*#!H-OcX3DrYn3SDkf4^8`r#XkYGFvg!9a}LJ*7PN9>s~^4!Vh4$V&!(? zY~w)`=dtk$&>cI2+hoVs-_`|rcS~>2IM$aQlod_Q!ncc2pw5SA72?1QBh#Xd&cnQU zR%1{|3i!ajr{?i}U8Wv^b6W=&@|`jA*Jq!=nJz}?o$C=^g|G~3z%-+xek(ymYt4+%zH&<8O2m&U1mlve&}R;f z$jGLhOxp{a%Z+^j7s|a^O`A)G2mCXp;_A?ovI4dB5yGH*%(571B$8I%we8S$d#B95 zjbywq3Hl*QZV|L5u1J4pJA2DWT?Geeb{6a-QL`1F4)JB96AZ9cicFTn_hg+PbCR-j zr4R+7a!`y{W2fdgZEi%shwGK2bj=giN;I_xoOdOhcR}UsnbV@Q&8c;u@$I!X9<17| zZ`y3=NLW1pmi8UrA^EMfdzXvpER#tcDiB|QSq6R8CSjrGVglP?@SQle)hfkEx#bn- zlre`!k4u?^(zKCWV=K(zt11iwQ@|>}v#a8fsv!^(;tN-Kw#zQ#$}HpRnvblMq)L>m zJt?`tT>-{X_D-P!zc<3pSPZ<-PBOIpq84eX$V3IX#e!b8pnzINK0s?VWmS(KAey&S z7?Cl3m=qnM5gn;giFXRY!;)(?eTy>unHv~QLqSwDoC+HT(*pm5YN~4{Bklr*^)_PF zN(N9uh${jD8ij4@+W znd!eVz$uD+3IIk_-ZG*9MM~8@6GPKqB9&1?>Z(v`jAD3@rD9C^5 zcTcGRFeXEpS&t)+E80H)?p~mFK>=Zi9z-4@cdS5~k`x@4^PHhLV=7M~*BKOxlo^RK z7I1%K=JC0xl+?w}Y#AShLollMwc^5bs4DCavOkwXbeN$Ha~W*Z`%#^h(Qdw8<6>$z z#kIvb*c?b=L`_*`s_ODse8$JgQQcU7&X8c0jIFaKbe2hR-iRKSo3Y>{jJ-nGg-Twk1{F4Ow=k5vVKR-}4viOIRQQnjW ze0lgci{)x+(meYN1}1}qmMFyH0|`-I^HC!a8s*Zy%nj0wbjJn}2!Y`Qzmh)UIdNLh z^M(Y?-Q~?^vNO&nU-wyl*i|3?GTbqSO=YSZ>3$#z0)vo&PsM8df>2mP7GNu)P(nYh zo|RXyFo{Bp%Z;Z~YOnL@X!pnxg*oJI%z*=meuA+%VA2l9bHz)aiXhkbDjC&B8R;>? zrWPZYU6{*>9(AK5?xhOnL7?GFq4)>1_9i;TmAdTY(^E)Clw)3VqTf5!4XN=#n{7vJ z)~I7z)is^ns87DqbKka{OMY+K05mED5j+p1HE(IH#ritY%FQi)$8(&yVrBZ@>{cy@L@k;lqeKzJkg#LOd9k1E4_g)l-)GpYs@SDMZW$!w=MCX zEC?#X7*;zf1d?03Io=Iiip|E=}Sw(ND8@8 z$0c!r0{MZ8mN$f+21#V(r3|}0Wduh9U+rfj82Ho?pBS4Mo2JgMe!GHS2c$tNAmu{6 zOV4tx*X4u_$GVYI74YTSLf&+8r;Da~Q3VeyI6jhWd~Z6Go$?uwh@B&u(kv^TP%%Sr z)59u@RT*}x`M~S0u@CHZJ`;^1g1w69QMm9@YHTrvs*`J^?vbi#4IzzX^sW|`By668 z1^bWz^|L9s3nMa~Wx`enwqNV{%S&c9JqJ1PRTJ9(dbd#j=c@e+vh(-C)ciBzqFoA4 z*%HtrSb!Laf{0$IKpH8EBbYEKR!pbtwJ}7qI=tSp;!f5ZNU$3a8TJq3tZf(~uq4oK zSWZrpi}}oXY@hG@Jyt*87X3g!9E#c&ZK3*54KZz~3g0kZL0kJ3!t=G!ZO;%vka+WzQml5Ij0DYW z1Ar4UIrba?mjw}!gXTX$<`H7goSdkQHI`p}8C)jp!;%`ykm*uVIpexq{Ta)y%8bm6 zty0mw{-irzq?vT@Q8N>?10-mt+4$O!Vid$00P9arIZs`DRfT5-Xy=T-HAyAi(G&u zEC^g5Y6)B&A-6$nnnYlA32mH$qopC<|WcsOR-@g2nk{MuJ`8ZN8+u#zNnFB_Rid5C=(#Ac2t~krN5$S*6OMnN95n z$5<`MLC+~uTh2BD;cSt_#K?rihM*tyS7t6JdM$J&dt0iZud;ovwx}`?JrR0e&a6IP z6kZ+lcRq(yzB#g9wivM=N^+9ot?Vm8xpd6#4;vvL-kEYLKzp(Z50cm(_a`9ZkKZYE zvt&w0II)NiHXx(lI^uH3Lq(C&9vVS$?32-^I0BR4P2WXq$tGT7LQ&i~Mh2_Ycvi!S z@3PuYkY>-k!$M7xWmD}soyn3ABsS^_t|B|H-^JFQ6rG8`mW7&a+*^-!j14}L_RNhjTy=8k4aSgc&uybOJ&y9c zF(!A52=-6BR;Ky#737Xg|L*nznCWmGK05;&66JLgT4v zABb$zyio_8M-+{>dGjMvJ#h;GNMjBx={oTS_B^t#T5D9S{&t|Tiwx%dXgz_Ryea&aUNH%o>BH?;Colxvc;X+D~WXZ;MENhiopZ6f+&u~A8e3;c0R2foK39W!}v*p zM^RoNfx-TEEfv$6v}T@uja_#R2v{mf4H?A7?`ZlC`6OPGdsQAUsHvsQzwW$gu!9GB*NM1o%*wah3fEC?sPCRjo02rLQrM7!x7w@fbWfn!sLI-CKF~wp^KioE zn-f*hNK(_BWr{4_+g>GA?qGayQd;+*l4ou_Q>e+dkZ(ar0u*g~68ec@MDUgO?~{D? z<8%ZMXh7^&G-^ic=1Qs+g{N!Ls)c;)@`r!x{et%LtYs(+bGHFr?9RFAXCw*HM zpXFOYWfot&f+?{ms77CAdhVe9AHbI_W_i$0a!{t`5A)!dUq^x=k_L{jiIH4ieHhi~ zkJKLmd&IBsbk~%4zF{=*0pp*q&*~oe!d*osp9<&J&#klphEZ{(t)a>JtINU|dFaZ% z0n4nG$Dhy$D#mxx2&2F*o@V($m>p=1xhbrUV$B1;>X9pK5hQ^5V+ZL+h^ulHHC0^F zqiG`z9?YABk?@R&l{js&l@%2bi?j1naVYKLgKshlny($lH;A2%A3>eHtrG^fs^D{e zOHYtCDT|%}dO-U!qe8t0BdnySbtBP#P^Q2+`3%;oj@$a~8ZjS;JVr{FBIY^B8yOUw zI3l1axvbAQ8tl^gfSGaaqdrJ;3RjYJ3opYk4mnLqpe|@H!O9gk2UMZ~lQoAc<3Qe( zSn{yh;`pVdMbPfX=af{^z|WytKUJNY!q>1udrI|yjHe$41NU;KFargSJ3^?Qb1%PF zqh_`=67diPjzaggit04Cl`xW5QRrU4h_58>vVm=g&_S2+6K9}ykFtEH*&*M*XjiJq z3wP;&Md&v(jfbyMEqD=eWDDr`qfWDB5(Rrav(QD>5iT1&)joJk#MRkVd?ng41WV%-m z^~1z3XwEELG0rB6RsF5bCF9lx8^`>?K0>gf5i=}$i}yWMtGFPhKBBgrs64p2UtOF% z)wil?lTW`5Inf9~+pHU+Ym6QDUSY(CDXMmO*AkLD90j>CV~-uGJtM`?MO1}|$s1uO z?S^0d6H z#>^L)zG+V$D{oK_QesF|b^n3dj=t`cc-clfIp6#dEQS7aExgE#Y=9De;wDzGssJ9s z=EiD4H=_uEM(#xi@1GACfZn0pXYsvdf_fIG_E=JVAil4To@JV77pV<5^@Q0;-DP=( z+#S=GsDNx~VYz8vjIJ(vJF-NeAua1WfcChSVe%`- zYb3P(zVzA|J*oM4XyqBXmv*1#nR@%9+g(8CB7LY^n^RuGrCoa*3>SNR(24mC=+(?O zrsu%TS7e0ahA7ggVbuZ4CIpnh0#JA?|8Dq@x=DiXU?oO*psjNTC1L6b;W7S<-b=U7 zv(-I0?X%S#=b+M@ePtkKe&P`?)6`GE2FV*(p4+iIzJDha9?M?Jf=SyXky$`yTB!JA4-OZ5RMtAjZjw2)WM`X;+}h@Vt4 z@&-u=p4``X406QZsNUMFb<@+CJQH@6)o2z=mr6kBGnBJj1 z&POlNHD~@INY^5CAScfrprWM&t65qpfiMbdS5cYE_vx9)Qi=V5ZUaI}u`n?5_@YEM zuu|@cdvK7c;a*ZGHp$R&gDlqL(y8rN`g(dY;i^;8 z&OYj?N3i@UqgWC@LNL5m+{C&ctAx2I5Q5!;oc0od2}pXWz|1nYQW$9myEwtrk$h5X z4O>DEU`RE!gg<7X5dcxaB?^E6^m4SNty5pMO@R*DHjyK6O9T^EXUuv12plh(&3YE#3oiTZoLgT-N3L% z!ZAmXxCMn!0R;@vbByAbBVydg2}5oW(c0a3;){byk4#JV{cFrHK`A8}rJ8pO?k1`q z!uBrJmHeYf=2E$0dLGVMX{~UPOEr7P&B4!30)8N-js_c0!`u~6O6fOBL~*gT$<`CU zc17`=lwohuDc6Q5_YRIHiZS<+x9g=Zd<;+R>bF?MCK3woc=DA{csmVuAe|%LHMLIy z6UZK|oG56bcy8_~^QgE?MOlt*&&bZX>od|OCKoy%{jcj!+2WL5Nv852^)O|xni8)0 zlLsLf!9IY|u8EcgB^cxM1!Z#wZ>WQa(X)gFgfL zuE~^MA_;p-KYxCOG|;_4|13c3mEd{%0d`Fi8|ZI@^cIY=Ye5@k;E4Yg8TCuRlld)l za@T_w@1q}{nt&k;#FNFW>J_O00*qhA>>)~3voFf(8BF_zC;2Pi9V47QA)?XIur&RL zmN7IuVv|!oC(^|pDK4!xqmHLz_;LPw6O)2&G+@_>`-Uo>UVH%AGq78I(2EnxJw8vz z5h-;+i(LpiH+r}}$-U;h?Hcvm_^5P#(fVzFp5>a>>g#l8;O=0T*Bi(^DC6;|KPvM| z1Y`gam228P{e;y6;51WcpN`fA%tQ1oHvf@Ka+HJ+2Cp()gteK{2D?YJAk`I^0YJlj zqwEIXZ*RD6951^sw!oH@!1gT%cCd;n!6hkSv{clOj?7tz*;z^YV09M`uOl|!iy@E8 zBQU2^YcoI4f{)RMW;D76e4JLDPA>|Lq92ht8}r0B=st@|3WGGBeoiV*lAJF@Qh{t? zQ8^ymkLs+rZ2|2jh1F$h9Rwt2rjTq~aUG7Ni?A&m-AZ#9Z`*;(z?qBz{yg+%3*j_W z`Le0Yi1_KN9rk#KCyr`Xnumzn6z+%!__(S(^K`InHW;7*SbX0WGfd5qRUN>Z4T9#$ zyYx%faxjxq#fsh3UfnL8;TZ4MPVSF(C)5W`>9iF!HM>I?*GxLTZFF4A0hAjxUl_R6 zT+_`ejv51dBtlvRwO?4FDD&?(V_B&e(#HmVO8@f18%l(jTM6#pV4~~QD)drPUO-Cv z<;w2X@el>LDLbP3al0rn5IJkI>M-?9>2f7Fu?*{Q6sQhC9bHD|P)~e{O+e%qKTy!m zpvL@&$p|L!S{}La%Lygc&nl?q8yDOy*VJ?u;9Tx_3Q`|&c#OC`UfL)YxTqrJO%SG3 zP81KbF-laj6~tH8;N*DnGwKi1v~Fp+P{ku}X@|EJ_YOeo3C;PE5_n9#R z%7pn^<13m6g>8e>b)h)&G1!g2v6~>aDvwVx2*>APg))V?V@ewXjsrp(CKm^XPC1j}VPg{ql$d4rSOBEmol*yf4nL;w z>Ma{`k{eAiaKg#v1)JNw!P9SKBP)*LgYs}JC_BLWbb}0Pod$K^gC(gP>Sj7(+%*?? z--%Bn7mv{+qn?qE(J_V^@P&ne^##-F@tJRg>-WVNQ5hn5>~jbB6`tszz$>T^_CFp7 zWosZTyt$Zq0@L-SWb24aS8j~a>#C09YsN*kfUh#ZkF*egc_6L&M4XxLc@sEoJCEr;DdiM9 z@#)8NVkHM#)ZOt1LN}X&h$!?JAS!xbLzKLRlG$?q!`KpzT(>XM(JJ>Zt3$5rg!Lvss z^hx^x^hr%J+JeG$Q><H)>lEp~?x44Ma%h2+G&tH~*NvjCem=W_zZ*Llv?+>?en?ZKI`ljY4S#+plv za-S$LEmh!ZmRJ@s#pxg!Zce-HTfJRx1_*#URD_xHj3(- z>Gv|vQx;ERHDl-D{9DSWijrK#+bPnX&2q{)F~$?cz+FOF94G-KXb3T#Fm%u~0ft2s zKb!KlKnbv_wpPnFMhv^4!dKM`-~17r*nw|i_f>@_s(N0|^V|0ZWm~U4_iHzmbyTiIOdWD6_v^bn~dkd+BSgGbPS`8TQiG!WR z?4*pbA1ZJgC=I%(y9jjaal_gaD1y<200=a}P{W7%t7AkTF!OjHHk}lUokFl)gna$r zOi$Q!eXP}KS9|juiOx%L99dgW&B?uWYhFL&aPftc>_ReqEpUqRMWX{M2Bi*lVbKaf zD~CP9!=dWcapBH}MB7zm18Ig#+tp92}xw_LZh$|!{Bes^tS@*cpvh>8s+ z<2HU;&gl-kFBN#555?+CQXs@A!@#?gbH8qnI%t)g^J@3(+(`~vv2p$eS*^%Onu&w)C!1r2O2g;&73GB5lv%lGodO&9lwx| z0wk(~nufeNHFQDGhKG~083Hzk%^c&}aXW|6uCv>b_0cp2URggyb!8&{a6b#{BK!=; z`So*8{I*H{S;ST_svXN^xF(&!ULtHwvbPngEQ-gev>k_Ln9sBDc+kw4rE}>0z+Y#M z0l(jEk4TpRe}qSrV}}AC05QD(T(}nD5MFjo(f}iXF0$!qvp|)wePwp9;t9{Ob zz6P75n#Tn2)-1mAD|k(fkY>UI!5b-Gz-+<3AH#`O?Zq%-V~Q;bQ*3S?8>&WS>!vzM zAkS4$1ML4u&Xcqo4;hZ4N`NR8oskyzV$SGl zACmIBY;m_9ajr9439xeqkYi#?3LgKc#SzU1rmNP&D)C2@ympa?*m%IqY#r!=z`90Y- z(Rn>_n#DOYvB+w@7^FRT(m6R{IvPO>=x6`0>tE{wKmmVtWe&U7bC{YczQ9(Q6;-Fc zAO45!TIsARsXsUw@@KOf(aphlF+x4v%(tedw6fWCHP34KlO+2H8E&iR(`HJe-hp>o zADw_MEa}H{Hg;WCursnUnxQSG$D_%F4oat{+O;GnJDSST$`+RzzpqV^!*sYd`nc2Q z&7wta-}!V+`}V#L&5Q2PPHBh1fVl)j;%Go?jWNJ%+$50R=iqJq{A$It89$^=lTbE2 zrNrVOUlIk=Ok{=zCcLFTX?tZBWl@QIqPjvmgI2!sOKJku(hf)ayNMjp!`(uQ$n4xU zNylEpmM*)LL@AXXRHZeJu>%ZSqWTE6G#i)=Imc|kPkdZ*NxmF8?O7JX3aXtFMQNiY zvDiaB^#azz9769qm+rZCa?wtq*^Q&`>%U<-u^orONdVkcz%!UE2i&tVkP9))I!jg^ zi0Lhn`jk9cxg?IxM5fzLG z!^Le8%d1c^hKe8|=7S{>YmOm}L5qZziijk4^5aJl?}#u&@n^vs2)+wN2eI`%6fFUu z-6BHP3)uj$tiM-O>1QvVv7NL@qA&xUSd+Y98#CmqgGUo2u*JPz>U1xFlSFuRK>J#I|dI zhveFj&l1JTrlZeRpSY&vEUOqOvW*VsDepX~WL-+>F)RFDYe}#{Bg&wItueDzpz6v= z-7CA68BE|0(U}&LhYs<_L_=vZf}!;lqWlB>J~r#I8ni%P@2sfh9o02n5uS$ANhceo zY&n2LA}6{jjAQV4FH=LPdAE%l@j_)=w`t(=U|P@KQ@_lX;dKVh5J9w#n0!}^Y|X*A z2iqk*+$P$PN>Pq_Hx%+0>MnxHfmJ0=0mBUC@pP*rhIbiAPiPyNp+bfN&$i=*`)&-^ zy2%iU2V(Wq7)8dZLWH(pQ|_W1q8=O8YB7NLUZjNX{O|(cNzG`uh$ga}pv6|@ex6mW1nLkuW(;u#w%{-w z-isX2h8ID`8}6llnWlBp7aL=i zqRMbJL|im8pmW|6b%2AP%=7ef2;6zL6D^Ud!uGQr*9PUF1fQ;W8|MC$D5iVKrU;B}k;u$?`+T&!WzXz>L07*(d@%@|j|iT7=bR>Eo@AnPqRYjheA2OSF!xtA=ij4?h)kNZ zPmMb!4vzChME&bXi5qmi9xITM@b;zw&Hc5*P3LCrOY6ILTts(29lt9TwI9$UeLya^ zYdj(^*LX*qZsGDo0!aXZ0b~y}Y{v<;(s%+zv3V+^3=`1ZJ9O87)WGzwtZ`fkGCvDr zSY4WgH(!??X{=u#KFe$FA8~bRN!05!#%;@&COXRv8-J=?5R^YEWPf%I)s8q<&{i+d#cIhsy`f-L~40gplqXGD}I7Zp!3LY|kR^X6+& zqY%O8sdhemw#VcvcHchbxnMTJl!lc@%S6)Q!G(stt-tBNlzYBNteLbA;n^&HX=lWoD}9cIPn_4(b-0!Uk=gtHtC*%`bbN1i zlKVL}<;G`TFXFt#Zo{<$kX9VR*hkW7_i7k4@Wup5mIBzK1nz&EWks0X^; zw9hnL9lE2a>fu$43Y*^8QgXUmUp>b0gGLCBTF6v@L8kOCoZm;`oN#@ZLOqyb>HBhf z(K3YiD_UtFE8g91c36V$hF-pK!-3$cF^NB<*iDn?yP z1yuv}16$m@KnqltQHiw>UIug3GH{;IK3xeB(rI#GidE#y6(Pe4k*${LwKsj}+`%gx zLA!w|MfLZ5m}<#wobt=e1%CekB#YXU@6&z9lb=P`w*ULDl4(2sG_){_*{AZJSJ^+>Q~Z@*8Dm%C({8V zI>2UZ)KWJdt(8z?&NEqo0yHPZEQvWgY1bDM!&oycsd03ekv_zUE1Cw|*xh4=5;YdH zwW5IDYa^WzSqm^u3cl6-+mxG4b&XGcBYP?T!Lq#h>Bz->fin%qqk?PKCOX=V+g?FC z$ll`!ceNgug<&zC&(f52Y3;p~(kDC6hLb86wdF}U37c(ExPT@PD-91C`!p#uY38Wf zl~_aa9Lr-tD+%}X0?1@g7DEBs5l+L7xoJ1^3l+F&Xwcn}leLw@G%<@I!EAewAjGKRO)X2ARU&Xg{pOJs{ z2F(8Wi%j$nsdL*(-o^2)+UN1Q=JPXTqb(Yl6jgr_-7OJ4ZE z=M^F6Gp=0v5EEnAr$gxJW2dcGW>dv@mphDZ9{s}geuHYD7yH-IF8lD1m?=%D8mW3|q z#_uUxs8bve&N7B=Y@WSz@wS#@4ibdxL%294qn;x!LuSXqU^n=#E?Y9wbf*)Pui95a zHg;LU>!=fa!P=Xb#tC822}TG=2}%e|2`Tul32OM2Vk@5IXdP=JIb+@ka2`umubl4r ziTm`yV}+r#sR<$|Shj>=pj@_P%l7A^Kp#F%@sOIQE`^8rx5Ws2_hKqj2w+p6@adak zhcc)aRJ3Z%R1UGPaySX96hp?19rNwGco z*!Lk-7AJ@9jVNN3H{(<=1+jz1_CmC3*B5Kob@Nnf@eZwjXQCg~8oPBp&|_aE@rC>f zeKnO8Vx}p**0jN)AX0h@9pz(1rt7e#S|*VP?t2 zDYj6)nUh!_JUj=GfDKYWQ;-ne$WWLpT*n z^p5PtW*%~+0WSAzuj&!79jLmdB8J8|hJ;hI&>LtGj})WMQe3Tzq#XFr;RR{xBUd*ep{ipg54cqpjx4ej1w@h4(Wcjbox?3p?emXa{V#x$gw^45p ze*=}9O*Yt%zCgFKukLvNS;v31kpE_6Z|dw|Wy;{<=IH3)?8@NI%3$Q^$nY=dCF$Sa z{f!Yf{=!!Okv^QGIBgBggqdCLR`pQ#cm!2U2_`ZSbP*Xw9cW0kwBWM^=YEk$E431K zR)8=UMlGj{sO_VfDbhQ|csCtCTla+UjideE@pLykpJ-Ur$^2QkF`g!H^U`-fwA>U` zx#HwI^P>7MM9>jYW%_dzRE)hPMqtgf*d&t^bQ=WadOVYB-*iw(M zn9(p)AvY=&v}-NY%~?B(DExFoo7z9}m%D+6*Anb9$bUq3#^-{EZz91QGV{IqmkxzB ziOscLV08LmkX&y?Q=lNB9m_O{DGN<+62!og=^h=sN716HIM??x)hz0`vAfoXGIG?~ zbLg5UQyl&_G@|2G1T0@f?99Kg#Q)AA3jgP!`S_29tkRu~9YwL-+#` z=`?9u zy0?xEMIK|K?obG=s;hN{tgEU-y9(80@FFhUp~g-Z@hnTix>sk~J{ zp&*Cz4TbxYY!k)Wir3?9Z~J(m@ZW$wD4kGxJntHR`ZTeCT-}|$gY@I_(9_y-rE{&3 zdm6dEBl3mJ5B7a0oeN}qR8z9iKTbc2sh16hERxZZ{4Q1>8*37HQ6-B=9zZ*!*CZ{9 zc0zT1>7&fGJ9KbN)G2y-uuv+HZp9v8+yNlV-2 zJ9<0%?7QmAA$dO)z@P_ihZA@zz)6j+MxZfdD+FrwJTR4gedZ@BRfrsoMnKqY+BJCEqc?h;tZwF2zuIo{Oazex}0e zECWj;TH>SI*Wu?4vfu)l;SD?L@f0F_aYs?=T?*%Me)H!bE68Wm#WNT7@NoxttI6u^MP-#Mo8h}5))HyS_^Eh`N35rKtmBc8+n>c&g zjJeb-tgJ0$S(aSa-cW@tYUxZ)0#1j;R#-o)EvxB4wf$$~QU(&AjY_eTtO9mrPLn0O zt{k~CC=v&r*>3ktFWy!UGoSfkbvrv{s{97>22Jrc88nBet4N!Ne0wk&1@LHytgA2&=X+?@~ z894K`q-)C@*k9z_xhCx3;gH16}Ji69;~)=wNjlT z^!0I67PY6EJuNw>5D$dcgWoVzlY9?QY=R!S>%z}Bjhc)(=`+q85?4f#(e`RLfUmg58y$XI5yJ+36Y~L1n0UPiIuz zZI(mGX#CM$(MS?Ka_BROff_w=>{wL3QJ#fdF8Z~z&!H=0FGqvw7#Zz{3N{C4UeBQc zZ!MWxAsjYW=QyA}NT^sRns+C7PFyhY$N<-SI7>%uekWsr7Xx>citP1u*er<>tfPyY zuMy4)#N(V0tz6(h^9A;x4ma!y*5Nna3hC@ZdqZTPc}BWSyNUb?SyyAa%M8@&rVkZJ zxCssB`Izl2>YJ>QKE_c*`4D2s*^RJRGtT=QVp@3IOy#c8((>M^>r~sD#mEz=S+^E$ zQTxg-U;Fyf_S82H)Fougs(mR_B~-f2^pL$|lHE1G$~?oUw6;H?$&oZ1!7Vai(X63% zR-`e-j7xvYu?gVhr(SQC_7#@CIW05FZW^Sv121$z?*O>KTsQ|4Ygd9zr)cIJ^+#Tz z=?#SjAI-4nW}UzYM)9CauUW7#(DaQSWiWeF7kdvH8}GF5!*yU?in~2MpVie7`26Wg z*O-qvQ`Peu)q}!3MJ*n}EKNktY4 zt7YsX4J2=-2+*;wN>=ZE|AC|w(bOi6yv(}@dhEvbHiTnr1(Jz0>M6%Z>SbUTx7yry zze}|*GSXgeZw`=`vgc;(cA)L#5O1URi-FsI6=Y@CPgDSNvOPekvX?v-!mAy-$2YK+OH{(k%$_w|hJ%oh7U3-3DDZq;hVk2@FFASsUkBej)lz zUdb+~iSeRb`Bu1nREUZwQlS$XoQiIWHDpIbZxy#2r9cdg-{J(x-nSW4Nd-v><#HGj zO=>MDz3LhmY55Kh3HoTRz2}VAw;|V{P)FAFajKvq3gI_zrb*N1`=*{-O_jFJjLE|g zur@;L>hyl6j40v!GKUF_dZ(oD5HK$gL#`-G?w~cVT!aPX9dJqRZ-$>o^=Pv!gbdu0 zZAcc(s#zvzfj`Jo z#qp~x|Bn!qjAJLd3$O&W{iT?l>D*$ zzR0%}vM?q+U?xGH*+Bl_q+VVj4qZv@A%NaUq@LtyV)~n} zeeCr=qAb{>dnFp7)}}i`fquoB3VD<(G=LpYWgE|lLBl62t*J%{SC+>k0K+`!Am@7$s6^d8$4 zcDHbnky)Iy)DrwrL;w8Mdk1=q2)>h(bDwm^c#=n$j#@<^77jLh6s{;D`pz%jjEXTr z*goIC`_10a$ur{v?%3|SF&%$|a_FZ4!7pU&&%eaY;G4z-59GIR?I{0E+%W#k_ ze{4H3)C_Ol{4ybQ6g$^a(<~hS;$;g1R)p*_J=Z3~t1b7ZC1)ueWeu7K$Lf=ZI~(dj z5JmfyH|$93K4hKcowwc+7CF7~Psci9Tm4os=5mVM=Ug?n_Mg|~Nxh?SAz01d-PoGv zq*rlTGS6OK_Dgu{mTz_N>+qpQ6CL7+^LPaY9f+rxMlJjg8P6p%7LuVsO zTAr_sBml$l8pqckKB>O&fk>Y{Vkn0n5)dL9JzU$mr?;L}B_e)PckCXOUcU{;f0te- zx5oc|b3z6R1#eQr0*o14!@if6Yw%XlM%L~pkuTuMm$YGd^LwT;JZ_U?DY+)L)JzdU z=iT=;d8Pb{?r#tthUX<~1@ZE;4?@&Qy)Qdz1G-aA2>@*bhrPG-v^IpBW##3lkA(vf zi;j<5ZDZ;f6O`@2T)GYZj89nO9nsM9&q>iGkI15fa)6_5hAHG=Su@)u0Dy}WRPn<1VqcMFv zg_OI=sAAUzm2s(xE4V{p8-Z?`8)1(>LXS6DEb|a~lzKKd)XPcBHl~e!tT0*6NtCS- zq!65;ZRLNK6Gy!NC6-Pzn#b0@H0Q~`_}~8B!%Fslzia++s?Y7=t2;c;;&XM9E3c4B zrq#GLn;KOK*4hwbhBfJ&lwf8u&dxrZUDD**dMUq^vqf1D3cBzk*bs#<9=LdcmIsj= zQy8WIOj1~e1XLNaC)mOK=T28ynMdmF>vw<4r;E$xoQ$0HoW-Kgo_+gooZ8tKKdyeY zbSVD#`TLODzV_(QXUkVWa2nzHEDUHZj^p`e52+sav{RWtx5dJ$@Kak%_2(E7Tx1${qIG(_-`MZDi zLtyR+<$8r@0j7Q#+2ikq7=T?X`A+qZdR;()_rDl>$1u^NC0VfQlx^F#eTt`S+qP}nwr$(CZQDA9soQ<; zo9;Vb_q_dU|IU>=_sYnO2pQb3hzuWx2iSyf8GxOk7uQ!_Hay!00yez6^N~%@{;3k~ z7d3$Ih#UnX-{44E5UPjpYPM($VqHRE*- z^my2y+^YS0P~V2^F11$PhxB_)A0tS>i>B%fDUl_F1QD=VHwHNeb8X1yDWVgwQKTq`xFdvXG>13`pTEn;Ww$5g8L~+&BME5~QlW}J zk$|^*(+>(*l#?M}lv_xU5Y|<@k38$ z&$mF{Z2~E;+LS$6o|%bwf2^Ivt8O}*K90OrH!as6%VIzbruiutam?0$5Mf<#x1oWS z)-hfOOWZNgLqH=8EowUs*GJ(N^pAvD=n$3Hb)P0XixxYfrlV)Yv}dwB44u zTfuxH_lEecsHpSwUWogrn?t&hV32j7evtZI=IWmZSs)>R!zHSL!=-K}kBEUG716+n z4CNGr1kNG|QH`Hb(8Y7vH#Z!uXlOz#yj+b9$pWKpGiE8p>QYZSs-lnwo<)jlUKmEZ zd^`?r#XGE-94vNgz5NI9DvZBMa1Fs2NtH>Q&e2sl#K223=`T#2VIcMRVY&bhk0c@6 zI_7qk{)&NN28+O&u8&q+=*yklQUSNVtJ`T6Kkir)O(uR3seI+slbCkghq8!11up{4 zovaDFUPTLKMl@(I#Stp`Wuakje2Q>J`v4BtY2qLf?KlUN7*Lrocz5_XOrhX}52U)O zNtM@J)t-=tXn9^K$u`3I8oaoWYb9xuqD$Zh8=d|i&UDMF+Mp|ZoVcoURh7c__dYT` z(Srr=4;)m^{?y7uv4su&Jn}lYPr6H<{6Smdc`kPWkC*v9+Yu%80jtM9_L6orO~VQk z2ZICCz)wJaoeM!&p_+A6iwmoB2-2ikzcE1o8HLY&GhLlYWtbD6rN)MXz|O^Ae2~(t0oU1 zP>l14P+DUIA6At1jUyaLiBV(R6jX`_r(XV+#xu2F=fnym z0+t{k8f3p${i*69h*s3-!k*5s0){7}B(IGHNzj9}JXQJmZ^Upu&yvR*`w;EX%;QL^ zmwv)uH?vlx<#1JKAQK*u#7fd|Lh)&xA_0=laJPU>4eT|gnld}i0!)Nsj{el4Bb74q z3Y8InP2p3Q6dYTS{##R7><)(cI5}GAvad&edyj@9t(UOO= z0FldI8+km!Prp_c9&zAc#1zHNqa#tKXT%Uo;}ZZ@EtEI~%M(m+Co?gRG(X9{;(JZr zL;C>T&;i-4x+P%y&9h4LDeNuS$?Lt zFBB?Z6AC!a599c8%Mp?kzb49dj}qcCQAduXBkFmpsLDWk=T4R8zQjsUydBQVBFC+mV>G5n1-EfiCbl<-kU>s6qPF1@o{8OxI@$rcwGWPJ@Ju*}$qYa2Np zF_7$yPxR+E3Icng4qk8`&$1(Kem<4Vm0p8nnzmxPA2B#*l;mviM+K2jC+=}*%i`a! zn30z^=WeE%UrLF6t_@gy>>G(-8V1m%aI}terZS<}fdTp>-p;z1a!5YPIC2)1jTX~1 z=u%aTpSeop)S5W2OV~XkFIdfUOfHEA=7GmR6*>{6o{kRB9OF!pV{!o|vsRoa5-Pr^ z4<~tIhY=|mmdTn7z5wNti(I5FPhTPT+zr~BGH77FnF;x4qn{`7Yn9l5=afFM6W<)+ zT>w1`M96%!uc(YH+c3R(d+{@S z^FrTfr)zTC*1txF()(~tkT*TZypdK?=9OnzGcFy=Ry-;Qhvysz+caTCJUK?%;T@MX zK`rA}#dRPM$hH8&#o+;;jjnHiv~zlD<2D*%C*USSKS))~`qbU-O}K$VIqcvwe+aok zxPoFiw5gb#zfv%jd5~uo*(!gFZaG6gVAZtW%N9()wiJxCe=~0zbpDD4T!TwJar&jXo{tD5CxY0F2>=sBLLW1B6RI zos=sI?E8>dF}qr(fOo-SGk#YENN0tDR4dpu%N|5M=esP^Tny;n!4vPgA>c84(C zHVB!4sKc2)QIi3=j!*px3QpU0h?)K_WY|LQQ({R>;uJ|}X{5p^WauZ^)Qe4|M3(~k z8=gsR*AR%F-D7Xp-oTJmlpOyZ*<`hA<{{ShFJJ>Z!ua}ZXv8l`Jmc<0mY%ASH-J+>#ouK-V;+1 zi=nu#19bVtp<%5MHFuAAdorXSK|NoSfv6GM3YoNsq|Kp)5Iq4QpZ=X)F|g^YVZ?fap00|c zH4q$qFGC)t%|$fi!#?CZ@!f#|FCDxf`}K=&uoAKoOh?wr4G?cRH*BX@Lh91kg)0J+ zJF92<_!x>?@_vQm7WB+=_J+FA?L`7lZ+v&(ppgx?fR2{PhJ-CYMdB*=lE-Okw?h)@ z#Ln$!?|pEod=D-5V_(x93GM~be>b5=T=IqT(oKm&#H6e<9t(*et&p1NHluQ0E3Pp) zR5I-3mvA%gdn{A^@sXS)u4eSplRb@L_XuooTM4&2k>NNN&_sNixUstjG6SehC2xWp zV-4xN*nCk!9g3PFA)UP8ylo`opDTDS7Zst3`t8d@$>LDzoPhxDgvmVfK`Np>A@aGo zu0K3_q=wdc0p8pO>IYqv78q^CuB}x+ywc958Veq;IM#?}Mo$g4Dv6-c`0Gg`4F`Op zHmVaI0+i&WyiP?=BUhJpNcQghGtv5F*B@Tn1ge@uAOuo@`I5pLbF8BS?boT`bZ ziiand%DFfgYGp=>?VR><(_sR)f(=%UE8B>3usdPawaba@+~A!C5(ueNnzlr?7*-OW z1&Lwh-o)!--o3LxoxAD_NZ&e2^rmwa%nIrXzEE5T_Ogc{bUT0^T&*f2nH8rszN+IK zxzC31ZwJU5x2138C%V!v;iaC!_noq@mvGpv62tHC_3w&uAE~~sYWMc|iLV*+545$G zSnJa+iK`t`N6a(uvK&<>_}Xz70HGvy0AA}x$}51=&BIMXr#I38KRkdIU(gjnS~U}3 zvlevT5JqZ02v^LHEM3V6!cLN>42hc)A9CxbT_R3^uX1y4;I9m;dX7kcEyS+HUw%IQ zJ%y{@uWS^sBzZ2>0Swy~!~Pmau*I8P=z&Tm;67x$+zr_|df#m*EUTdsFl4HX{p)@rGA$ z10h~MzWo8eTP6`r{pIR+q|f)i;exqbVG2L;i z`koBvcfzONM${tH`Ck<#;J89)hU)}O++N5hT=e>Kr^0>vxrCXcMEbpq5@S*ao!#8j)Lo}I~*4-3foK78?zHk*oi1|;2rXiNO6Jz@lA44Z<ZO!DLHMgq^ZWo{Uce>hIX`LgGDunc-Qsj_%axTIK5>m=^Iym$d@y^6sw&6DWg zGw$aN0DmYCqr`IxXg-g2AR1Uvrg*^}uFJ}cP4}H|R7SgWNUm!HDZb|Fy5^dP{!ADQ zZBPvo!a+oAA$Ffp=rKggk0Oxh6@>(bi z7!)2X|BBZ5l-2oxFrns!fS2K5*gBZma6a@wC*hM|ot;=aC{(LgSxRFQBplJ?nmMLv zZY)E19ITd3_7yRHLA6Py1}*Bdl?4;UwO<>(Fd z8#i?e23E?$3A5xCY5c?H0bN^{2U{ipo|bjBgAx0$;-05R{WV*Fbz%e!_%~>z9C__m zXvsScWQEhrDVN3dq4^KdGc*ZCTTmQzLImYaz&Qa|#KatGVK%A&NX{AxFYE?#;ZKBp zxaM}^NCwp&5!m*_!j~z})gb+@KeMl6xE|ThpR*V|B>puqRyWz0P>+BTo_{ z(G24ls%8{!7YU3yDI+2^Zkb68z_pbbi=SFixRAFFPG?SzMAi@%&zQw*|Ly+L(EZP$Jf#HnU@1hjV!I;PGm?3AqaxNTNfk zhMgFkU53kGl9w!*AbiCoqsRtcc(EXVQzaz9O_#5;%+Ej)E$X+N3@(24N#}XvoY^ zXib~8m1yNi4q@5M93SBPQlFZVw{E`G#PX>+Ddr)11SKcPiy_HF`~ABj;lzZ&5V?q&ty4l1{xNH^16B|&siGt)#}V<P-RJ|EM!9N0jTb??*67c9KcmIa08$DpAd& za~S4{g1aC2oX|y(7m`i&g?Q8T=R{{o4NK#7%i?y%M^NTPtLkYPY8-#6CYzM~(~=yP z#AnshT+oZllO7hwJH6R^noobRq{~1SU-x^l2GNx#K~*J1FgErSD$~}R){Iwrs#R6i zE0dZi)8e+;kLi^vQt8N1rObw>zn7=Krw^si%SNfcadIHcl!8Tlyq#bzYZMnJ`}njo zI|yk9yB)572XbHO$d-R%4O`swLSOOOM*hfeFK!3Gtp7zG;PVZ9CeSSP0#32O8*o}D zyLGryXqEU2ojv~rMQ4#SpmBJEcMp-jzI&>JKvj<)|C5j$EP#i##h zA|ng^ZzE!g|9RN;4>{Ij+1kbKOdj?>xwa(+q+)=_(*j>C@L>iiOZQ!dl`{CLsI`gC)Tp_A36 zeXskbYvr*?D(>kuXUFSn$AApa9liJ0efyk$fHbx}5fs=%E#QvbzBilwELlb((x-Ln z@#mFcBlR(|(*Kq2`$gMfc4h+-7Pd-q_TS zg8`&=b0sX7-DH$_0^-SBky}Md45p5^oLj_@#Abkw`T{@JHvjL5^<6dB_s}_1U0bfE@t~&A&5hCRj>0Mxb+SSd@T9Ewln8JkKi;3coK;5Nb1>`G)-+``ku5G{ zAeJHP1)zlHl|;39T&M~y!pxvl;jAO)M0?L!QG12eLydt*J|vlQ*ih%{j)Nfl5W}w3 zF{NXL!^kHk7&ovXoXkA3X!0G7G<6h}SJ`QPzpFy6`rs)=44_h-CSp0{){wZejUVqqMirghy zGdYmpR>+u^SEs4#9AlZ~i8QfoSAiL95S6ETR=z2d>~Co`J)f#?)66Mxkrk9_=|%k5 zqf&4n+^>g7akz00TLu=c7XtT$R*ifT3dbyLOnS0KmSMt82ZLtX%SIz|!XK)h?s zCU{&mm77Y8&$I7np4hGy;e6IlPZtGhZ?BXc`)yAio?MY{YduJqR`hZUzn6!Pi=-t5 z7Xttp1JUo}=zN#MRm+4CU~mwxkKz9n`i- zvGfhbzg7yJw5ZYL#hV=6G#Zjj=qA{|f^Z5fRnyc~_ta09^~bIQjZp_b0^2=Q zx#p^?pe4M>o6&sD=fwEYob3psuHYfpd!I~~%@X6&pupk9Z^&DLQ?g0t*C1(upl;bd zvOLyaA;<#1`=r^0%PC&To+(~apudy%v@WqE7Lx4*9{2*+4ji(~q%V|s_aBumHTu44 z{1dS6$+1clBD*l|!}{q8J5a{+EkSbnOHei=v>-Xi|L}vS`=jqeI_C@a!D2K|%!bwa zUtqv)%vQ_Nc2~wGXiASOj7q&hUiY&hU!pA84AVe%hih;=1qZOAhneD-50=Kls5Dw= z8DGAgFRfZ`bx1uplQqS&uhI}@W4N=Mr~DApLoCvr5=riy?W0V} zf+tV5wlHMOw{1r&&fN(+t29oe=D7~X&taChh0tAD^Nd6@rCH3v4NKX7u>s|)+$cH` zP(rS2)`oYXIU|LXr(^^dkgRWV}=$mQ(b% z9Uw{RI9}|D=30-c(4=cyIQn7h(3>_z$D)sjB?Yc4JdecLgdnV0ozlk%YxE^8SmNFZ zIaIQ258)`BKZlC%PV^dMrz0V%GjA6xRm6?5HhGZ|rMxln)PpEXCeXf4!%k5W7IjbB zl=n z8%MD#hpemPZ|$by#gcULU?uKHth_Z^M_qzKKj$ z-ifP#gcVw~lczqf(OBBC1LDKm*6=%^R9_JC5yZ)1^V8Tr;rvKjr+aC&SSqO>rx=HX zIWyajC9ygO=)UvEc8>+Qq$U7C!}bDF)nqM&|pe5Ri}n?W8SXvsrzGhhvQ<($#p;78&5*GYq5O6>yXYFx&e70zWb@b`1QT#b=|_RR4IA=U$}W|&|r zB;0<0E4s%mFt7hXD=675#K4DEaTv|RM0pCssH)ZwyV|fh9B-gy@_~|P>KzXCl$|Fs zoEA$JsdQ*is{RcjB&CK%y*90$mj{}y7)7lhOm8G?U@iK% z)(t~8PMqF0y(To*@e^(KtdjIA0KB^Rw2blo^X2drqA#I7l)O|&$sEA;epJ+ggt=!nLhi%8$RD`aCDBT3r{M+o zk|UR2y^(hTs|meseFbqpQzJrb31BxoWm8Z)qe09};viLvYHYXQ@oqa-5E(~35nC_37zbc6ON>fLa`FMnGw3|N=J;c zSVH@0St6*}LW2O6T2XQI;Gtp10XZMbXQ$u@=F!I$Ak!kJ&|x*7IZku$q8PtYhFn`< zH?@QT5s2oYC=mIIQhKdug zTYImesx@oKJ{sVe?k`{7tC$`xo*s;GIAqC*q{NKV#Ec}xjD0VDuzKrE}BQLX8Jf`FlDppAmadPYsi10af$)I2w*t~YNsFY*`Ki54GFf6%Ghk)CIeyr?l1slb z-S8;KqTWFM0Sx8@T|zqh^Hy90=0{xJ(Ck>1vkiNmYO;$f$hcuOdAw2DeOQ2RCGzR7 znxXR@KANv(*wtRN!`!i+%1-YmmLeQkm2ZS{zOQm#s&YZ*vMy)U5Vv{=rnvwPOG5=+ zzp=TWc-5*HR$Q*sY0=cGAld@C zeWUPQVBtH~pF+<^@5Y9t8n-?;Sd(-WBy^3x=EP&9C8@OCXX^!GQs zf+;o!_CQP_JLEon%bVN0}OxAF&ae9@wMY-~Ztuv(X&7y!68py!h#t{%5Wr z)&E_uM9lb~-BOgImCd{?vNx@xqa!(vLa~Fx0>g;zd>%2TS~B`RBC6vLa_61Lb~$ao zk=XxelJ*+^+V{GKXT;rdErk#p63ca4DY%oKwhp4}$^B|6F<-TLn;z9QODQ#gk9=$i#jFO~3cmxcHKYPjy z5j8t@ltYJwXwJs9{%>@ibJ?R}I}ZW}offVTp{0bKde19seiBkgI+(f>w}D!!=OSrNpC+#)B;Nf-r5eQ*qPy}Jb)k`Ni~RUL>Uj)RTXfX#u?h@kFHo-1 zd1|R98R%x|V^__m%z^2!QxVcp4GbN{y<2-7mbBcv++&>!tsDVh!TQp_aZgFkI%#R= zK3zODcAhFJ!%!obIQ_^`jS$8g?Fo*oNRAq*3jxx~QOk8DieJ#m@8N?Z=netdoQST` z8IO~L%|X=mvmu6nE#O5M+eoy+HXV-;l^;N3S4o|BAi>9C!`#Z5dmuy02Gy8lgdZ3w z&DKPC4;!k3S?E>=w8`Y!8ZWibKvZay%wN1}6?OA00z9ErA*v-U{NI?m+1J=_#ECT?`;2INLu6by|Vvos^eGURjO1W zJh7EEL2@(UIH<|wyMDv*!>r24~-42&#y`7`)zXl$WoY2f=ks=z;qtNb{rWZH zK_~P5*DnN+da$Qo)&D_&9WzI^jt5%D+qT=37Je!yzfF|dQ=S>EqLnyOW^bOpgs*D9 zp5ENHO|?znu^PE+CeRM08up-}RV3D1`mq{i>SX8^%KtiovKq>ObQ8|AMecW!Ts-Vi2;6OPGgfID|t3D~|?wN)`#G9|lVQj)VK&z1AV zSY;l*?dBbo3~62c+@Hx@U2*fKD!9VP#tvnf3!vaC{PnyNq-G=1eQDN&I!iX*R`zNW z#yf;WLq3isN(-CXr^bSpw&EmZdY{fIl0`$=g!6f@D4~>!j>T$T8-Zn(ggcbxDw_*> zoD{`8S_k~94z&#Cy?GdQ4^FGqium>e^k{#jq-Q!TnS!=fFPMq32LdhTN%eTp}1 z%HBGT^Tw$}Ya0ufs6_vPk*$hc_p~(Dts_Wv(#wcqYmhG`W&d2sYx;%ZcFXdWTDH?J zF~Pv#r4q6ZrwwESoB11SRmW;UtbN=%Xb ztL#iM(VZ#GW~*7|=E07&%DO5`k#)rLhWTn~LG)OrVZy>HW8O}w`pFAKtOOb-?CIF2 zE)#Sw0g9p=h{YRrB=D{I-*WJis?lk1?nPMx-ZA0Mq|hTxG&6fp!^)Gg))~r}hmW)<)Xa1m|IR<8O2C3v= zSP2mh)yxWAb1`cq2@NubIIk{w`~&NSRMPjddWA!LVKLaZr89%;3TbgI zU@;>S6iF(XWveuSei15g4c7M43B+Y1BMPS`if0^FV^TW!43^BmPt5Ir7sMCHA?X3g z%Eej{<|}r&fjZUdJ$~-OJv~pQzDqmLs(s(!nmq&v9Z*dq$oq(y?;Krmi46 z1!N+Gt&A3=XOJ*EBNh2>QUh?dvIB5;L@<2AGR&RPIp(ivzpqYSgTi&pU4d-MUz37$ zpw4>wY|=uA*34gVyleL0UJJtc%wCzk^7m?9u@uZCzv+9G&%-!^#u@*(oX}q%m%erc z`|RdGs_$4|8CO-;3X{5Vq|s5zAdhfQ!~!X^<6ZE~oSGhSa@y#Fq4=G#fKEED73uLi zZXOhTtkWk6*Jk}GEF+Vs0lKq`nV9bvlSQe1yJ*yrqS zypPwh!lJOa{T^)Jj6L&GrZj4&iWjqhT96jMtQ`d8TUa%JG)jXP;p|I_w~CIui+bad zYT^EMA)#OY2(PFmkt||YX#?uLRRMNVt2=;L(fzJOb0%NeuH+O5;^(2^E^5W^e(m9o$gy^R5K z@F8v*>17Z09v>{tzf@VMMHpfM#X4aSqtLHYAfvu-=sC^MKTgEXBGBtwi0W^mO5uOVk*;N zP;2a0L(n;3&8w$xojp3_Bkm{kYe7%W$ta>U8zsNk-}r0b?YB<d4%Wum2f3K>W*OK1D1&o>1B>{YCGwFBl}nN6j7x7f{0`62Iwj9mtcWv<<8{6N30cgXHc)H{YjnSP>pIU3u zwN+@ng}p{@F8Mm2W-FT}e*E<0dJ4> zY%6q!jvHOCvSQ#J*AIVVV)WZyau@}=j|$^SMed{mV{b+F#zMl;ispP>eX*&j)WSk; zAzeLP$g#pk-w(cU$oh=uTOX9w;u2j;1 zK?byT4XGuYd4EU0=>b9tHZEBs@7<;Ero&6Vy(Ud-Jll^D}i!p0R@d0iLu9W$TTD`LS`4<=!LpW)+mK%X$A5K@H2s?H3CO z?q7zC9S*0E6I)=j=t;e5=yhF*!I?ylk!MPy6^*v!y-p43SloJ!LzGZnOj3t_d1FO~%uW=-Iy~u4z-wD@_@-Ux1M6y6Rx^YY6jBV5r-Knu?mJZ5 zh~@Ia-|=-KA=F{st$?A{v4(MP;^sEhEL;~i|0b@5n}S>~CtCVDn@`U@gV6N`35&m6 zETZVQ=5H~FCx>x!*JY}Oh}=6wXbuatArLnUug*iZ2sRP1i4`ZCH@*Z$L=bn-F{|2A zx*O#(kL5pw;5ed9eH`5&-1}Y#CT&plYiHP-yC3tGoOF)?^!xx?8gqoq2FYSpzuP_L z;6i!xB-Lkz=|sCX%JY5O5ACcbW%SIbTTN##;YsN%588_{=Z(S> zez#gdl}W|~R7bi85-zAUK3-eF%}}$~ol`U?c+?Dv=dgfRX0Ah{%z(_n8*4gV&a)Q% z35;Toi18e5zo1gTzeSgu0{4@nuqOW`XoYW@iNR-CI$wE&;1Ta1w_Lj$N@#yb0Dw-k z|Jru_yLbir|J-&dnCjX8Q@Voqzr2fC*;@W{VkJ8v4#W>%8O?z7KwpuAkNdbUbeEg~ zs7J6*uV;Nl zOfEILZhU+_^NY@wFKLQ!$ zUbBAi6Q zO~S7s%9~w-ylWf#gB4>$#Fvi<nnc7}LW@33>R6riOH0v3OIgY8%9TBgz_|go>}AzA|TCN9WCq z^F$O%^Mh_25q_1wt1|h`rV(I(wKDiw{HAKvZ^5>w_|7TA-IquZ?5Ps>UHRlcc(@Gb zA_VY1L7)3y1JC&XANc>m!zE_;XYM9g{DX-byrasmTSFO{_&(#rzB7ri3vH*5ifctQbpjRTtg^$ddO$fAb;)|to&k`)tju>Dy zF+SH*XoL&Ae{zXu-Y4QC^xeG#@l)ioLJ*E;N@@q^MtRT1dTQU29kTuoqiWZ3Q3+H2 z18Ubz@IG%bNSOTggh{ZX7=NIJ;;ap^lxXGusUomSn~5+miX(151W|4qm52v#JYox; z_PcvWS=^IY5z1qzCBZLh^n37I)Fbe%@7!Px%~}JP=H+Ow&T_c@HH1>n=!156v;n3E zCA769)#A$3MnKrrMa~_eG=?;XdM(qCNQ1@7ebr#Jx+ccuJ*GT=;=alimw7|)5Uk1z z11~5$fZ7rYMd0k-=#g-xPioViJ^(9lNvs-jCs7WHy0$^$yV0-qBZn}s$z@uzH`< zQKgP=Y@Y_b6714Ow2NYaqL?=Z-W;g^LpBNCk$HqeD-}jY6^q+K$^DK?z97})g#L_4 z60@ZaVBCtyn4yo`C`vi4Xb1_tAT!DV`ytX`U%Ef7ZyrSY4ft%r;jtNd6X*11?@QO) zH-sCmYWz;M7un(|VQ-UY^4`s`Hr$BmFV;UQ!|!4;1^yo(f#knYUjMzs(*4f~`hP0H ze_B2g%h>)C-TE=<9i)fj=zKT!DTrlkdj{;f@xb zti85B$`E~*&NRnK8#J@w(zG~<^=OF-9BjKKJfK^8qD3$xT8GBbK4q#^2)?Eo(8!Y= z?7qcX5Q`IdLiwc!n+RQ|xH)zx*yL0g(?iIU_J+|I30}~g8%%T!W8*+3Ww?utK5(Oj zaZ(AhCeJMvrMvn@VRAE5a)l(dlC8+NR&uATOlP)SFiO^+PL;$iF;Gm8)`<~oG8@H> zt7%Wf)M1;PU?Fx<$(q0Dx-Vqhy=TL&LnfP zjhwVj=JDn7K{8kn5trKchNNY&J#1g{zU>?g=m6-{ zs`2Aipj77V<(}zg$!;pBr+EojcX$bmz6j_b9)pQbSI{1I_I*+E2kWqe04ce@Hg8=%eOh(E3{ zSroz`IRGm2D*EGPRmd7RaD^sDC&|!a@{n})Ec0z)RB7GwIbS!SBX%z^GJy;pRkk0v zCaO)!$eISXXp${%@|qP@Rsj*TdA?OBqt0g42GrDC`;t& zT@w-5o@57<_vgB1FYWR2pxFI)Y1cir#^~L*ZVyIm7u25+suU(WTF2|(EoL2qb*cVR zi5$uefQs}JZIez{X`a3D%8iR^->dB-lT%pUR7WoL7?XOuUB4lms0%+4QR@bwJ=Be< zM^44d@Ae@6@kz&vy^luzocHK|JMVx0r2jAeIsg3G|KqmwFU&egLCa==9+}6w!+7i$ zl>yEUeQqr)4peRz3_+i6zC0MBu;BibRMj+*9pOmX;EVue#^8ULp10BlNrQ*6$Xi#- zOn=_qJ-y)R^Z>dBg3*?@9{2S*p{dvo3`uR?k7~HsZuH@RxnPtZ%N|FCKxb%GgK{PX z(9_jZFOgzfg>X;w^Gt<=$r|TS@glb;7~a7S@x+Ozmq6<|WcMxu3L3HDfCnE{EABhR zJqCG?{AD1Z+G5_n16-M}F3}xg9R&dGDM*~{V3={>A6>?F!ip(7s;5O>E57QxC<=-m z%x)x6{tjQ|+$WNT=~k4>JeG%f3F43hgT>^%&buB6Ix!e?f2sS)&4QrbKUf)s2i#f= zih=v+p_PJ!QnJ z!x&}I5o1*Q!vYDZK9GfO?7|c)K?^i-42>nu4?3IImVbE)#6Gj6OP&BPm?vSS`Uq94 zjAeX{JB4l#Jq2dsTBIx@T>1Y(soMI_pFo^&uTfrtN7YGoA0a`pXa;6gC@q#?XzS|T z+t8pZ_}9UZ$H?gw-7}zW&(ym$!*YpaWo3@HvQDXz&M?yLF?vxs?p5m>Aqua6CY+G{ zBZJcQ&fE5XGN=&fzgCQY&me}M+VMX~BmV2U`2Pi#vy?R)kc`m1o7YIKRNVsw$eVIQ z&D=xrUCC7~p=g%oQ9b+#_gUAPp~kE?w;u7yLrbxRMzCx$@1)!Aewh%na~`+`F?}KX z1Rgwitrd%jl`Ne-eoEiGbk2CZZeQwrf4p<~3cgZC8cQl0z!e9kqV8*=pD-W|gLEPt z-{-4#V-1sZk|npNP6f*a1j3KOL)S5p4R*?E!EYFYrwo`58lqH(GLQ(hLnfnN!7~zc z*5K36ah2xkz1DY^jwrOV;NiVsFQoGo>w5H9wPjnoDY#QwDE7(8y4@@85I-fQ0kjG7 zYq|H%oh$?&WzEreZRbims$nu4g!rqOIH9`pb}U6g~liK=wJjqy7%xUJQTR|;~yCOkKakxM_F=kf3K78ph9 z&(sFeW=#}+l&G_26%^VH!kc=^+@XpqavhkU41V>nm6>p3B!_cwBBZl*c5;E`3tDO1 znqoN|xhA9)Ue7r`q-#VJ*CFTRqdQ(&inPmR)zZk6z)h}PMUIsY zh*Jq>7%XoEE#WVvRoBw*uAa%^k*Npw)iE}koJPv(!X&r#f_J>8$mKvRT}pA=h8AyzzRD~3fGJslQ;M16^isFX)~gM!O7=oL%M zgbj!x>=kcFn<8m_0*dn4d=nFsl!OgJbLz2FO~=a-9;u^7fKj-^+e~ zK<8MrMsYp*bg_AO z$)Zr)(r=8Ig|KG5J6CAIeot^*s9pJZ95g)HY&Dl z+h)bKZ95hFq`&U9_v&w-)#vQ%nm^~yXT0Mcw;qMVuYDC`Pc1!bI|H3F43YX5Eu;0f znpF3usZn{CN21bU^?mfds56CR5geTp+8Yw>v_x`Pg~&HK zI7PjpV7v6=3WkzL%Ml3SFMdFr%KlLSH$uMnUYwH$zi@m+I`{2&1lSDu)V`M^0S%8M zn@6lOiZbGanD=u>08v+CK2ofQ#WX+ecLQNLiSJ>uptOn>!UHzotW$Psel1G$Tu7*AZl$Nw-5CN}2w417?>|s^Ip)fq3iPJ}=MS#B=|#4$r86*_z<=p+UsJ52_L$mp|9 zLpViO#t@OPW`LL&*f>ZVM0dadtqa=thGNmHY~L}c@gDL}Rqt+1SHOz#OH-KOoc#Lo zpT8S7aCMq;f^$lx?8_zhaEN8(b5ub%r@8048@B)jgNUzMY;gi_jJ-HJhDfy-_&{XZ(v)!HC$hPcSIeCs9QKZ%PR{p zA3=k+(Y5({CUDXo_R9-3>G8%g_8}D}Puk)TQw%Q82wfAY*XCNMvTxA;xPYviMi~gf zzI}Uy{qGmh-}wsB|L+Tk-@wt#+04<6SjNU$(8k)>%*4rF&(X}rTHM;fQP0}I=wC&> zg$kOISp0yGAA=RrbLNd^jV}D|9>-17-~;#pp!78wreRm4?R&je zd_GDismvj!f`L5at=>nRCdQN1TfE*tPref@sMo~Z_1~sIlgRAM%hpr7%{?U)p&Vw_ zpUfO7keex|CCX+~A%Wv-M-?d>yI0w3>?z>kOR(`2dWJOx6V2=s6M;CF5IZH$1x*qs zovR<$Zn;R4>O$wM0LMDJCz_HbwG{74Yd+zR`m?3X6tH7uWD!m~cLrj@h?i3k7BBd$ z2@+%bv`0Jed3yX!3CxVio?VEx)~_wru3~8nX5jIJ)kmiH2`bjIx;yvj27bnd3f?UT zYG!Uq(jv3ox$-pc)hPjg4C+Q->viWMQMPpVhL4AjkrS1ZG8o)*BtmHnjL3FecP;ch< zq{C7DF!*m?Cj$!RQ7{qfj(^!>d5%o_lVK!??>%{C`AyYg*vhu}vi=Qrppy;+acJGyvW z$Zh!!+1^*+r*AxDJM<6l1dw>fdwWPcy@Sy&H}qd^l0k2fEVm=ycmic#Z!mbXAaZa_ zh&_`cvkfq_O=i)EJ!2z(Lgm07rM`d~KN&&()Z0@f@s#deBJuS1;vQl1X7nw-rsnOU z-iZmg0=Z`D8Y}7|-FdbA+TH9T-wXflD&kAa>{#uqyPLpJE>suBgCnj{R3r-zp@ztO z_p9)DF(8h*3@FWB&`dIYp~3-Z@dtq008`^f-u`XuA1;h%2fGagC&_MiSrV&dMMRUp z1eJq42^L8mILec`Q6{}=nklN5}hgQQi_WTSSl%1W{B~)xia~u!mBi5iHcZivd1xtq=-oQoYAApB}AAnWVM;|)eGh1 zMoc<_@d9*g+T_NMVCTZdFPoU-7{f~Iq{$YOBn%Jf%nd_!%L0nZ^9R<&7o^BZ>nX+} zVpZyp!%AyyToe>K$f&XA9Vb?4b1HGuAqAR^nFu>>VG%TQQO+0aRlK-6hejxgbdM() zjHt_3B^th0(kYB|YGoBLb9Z(y)T7MT2W)hS5lB3U-}mH|6|2{!i%p0( z`zB>=rZv#NvDviA&oQ2=e;3f|mVhTV2W(tSJNgzGunUhB!B7-tZ6b4JWhpRG>$*J~ zuw^v368JY!I6hZss7z?8=f z^Q+>6_^mfHG|2aH2>_QRQyckfeW)r# zY*LcZy_1XB;Mh}O1o$=0kBuA!_?3552K6&kD&{^%>s_+&XIi6j%uW?deIe{y2@XaVEo$NL2kP(m8;`f1=r3Ls)(5HP2=>9(_rfv6 zkda`c#!bo}7J!t-FfO-Bek%7|@~}6>AhSoy@DcV~eq%G~LO^u*iSvVCFZ(Ik zmy@kYeUbh?qSOtQf%7m+F+J%L`_;4H)d2R&*e+`SPv`U``*_D|SM{az2)oH6m0RT^ zH`Ox;cAnr#niw0+2}{0$a@{$~Ongby+_(12#Tvn~U5>EYw7j>+`9Hr0UeX!x*%acjQ$cpn4gU5B~KraX$u2bcqE{$8$63S7J!b~0^*OJRSBa0_G4^`bC zs>~j(tem@BpV08Iftu`Bf4K-dQrr45#63&YhkJ7P5i|pr%=kqtqv{ITszY2MIty3f zn{Z?Ve^QfKZQHrbL!%N{B8QlVLX***C2`NEV$X+r_-oo@5_H9gkthppxa^dRTSt%9 z?O}-SWcA8f93;id)(LWA0YX*@AA~DlkF94-gicLhEL=?y_7AZO*3gYJ+CBs3d5tWh z*qL<28KvHZTg4@%K~=garDmI-vgI+E9{266ou4DchK}gkzEgv&j_Yyya}YXYV8SV^oGcjxF;CpfXNJjPVbK!hL-`#Ws=D~U)RPw{GyJ!^j^+u8P4-N z2&d<%ws(dW;?Dz1GQHb@KeI`zaa!RbNIwZxXpzgY`cHqn^s7?nvmFn}^@v+jG$&1K zX9g~{lu9k}FAws&W`@U<`cL=qKe3|m-$S|63)nz(phr|ndUrh;f~DEj^CgOHf|6I)>E8v zSP^5kEI@KzwRGM{o50ntk6wmBNaxpgfUjk@U9-f!gG(DK>BC63rN;6YRqf3rId3BG zY>k^0aa57VB#l)t~$&)sD^tl*}K!rI0Wb5-@q z^Ol4dRMXamgVkSt4eN?k()fg+Ja{_Wp`@9|nNbP{Do3~*- zMF(7zJ!Sa`dG$4`T23jJ8LKqahgj->F}w|1f$Po!eyRAR986+Xkps?ge;3f60T)?Q z!$#~onuutTLsAl%mY~Aimslkluhv7g0kOL0(%Gu0srPC8;XJvpdY*|hn>55Gs2Ihf zepV-PP-k-pQj?#?>G-X0m>j@qE3GnK~Y$3um2xFr{m$q%@3>8t9El73BFfi%FM`ngY4pD6t;VT2ixA^~*-$5~p=} zFL#4fiI=h|Q)H}A_MFPJ50gLuGcN*vdDJeFa=HgEoc{&q= zo?nDa*$v2D7U?aAY*opnj^4R%;vuP9&y?S|843OOK7XTlstAaiGoYjvp6-!8QLU0t zmg_oZTE#xxM#N&gsMMUI zR)kI#3PO?*3`66Xr?1y=6wZ=SE81td+G8H4cv*4_9G9|b;v#|5ida9zg)o5BuuG%)HFr6|M8acwS!IlrVWK^A$2q3)E z-`^j~Svgwl2)f|P@pJ>*cNG9t8UINs*rQYy72hJp5|H#pxAuOKNB>?Mp;@8Rp@!n&7y5@J@lTIH{NHzi;hHaAPZTAknT_sm~AHZ$fsA<)%*Du#4 zLRZH(lB5Bk_UZd41JXh zXi?|zg5kvLW(i+Y8F-}(ebo$TfwGB$OPb=OjTYw&KRe$FI@@rm?W6$vlp*}|Q+Zk08Gqeo@eMs>dP0p%>0_2eZ+TotCh-+t za2;bmT()D|2MMPlWw_GvM&t5psF&~Zqlh75_C#aFI3Z9tB4Eg0c1LAhb`PvciLobBS$+oaE~Rjj!umw%=stjeypI~w{D;1jho5F%o~ZR zdxkc_x(-Sqw-`g%nSyA&W_xVWgkZYDjB7*Odr%ODVmtMs8MBm4AX{qLMzFS-hn~Ee zD8=8AzcTv8-P%cBu-aL0F?_@arwh1HHR6P}Dfv~WKyAb`d|9Z>Cf;#E(^@b}MlB(h zu(#9X6WE$jtMY$blJ|1s_)&_l+s9O7C$!+U>TzqIHZqSI&A0JkA#OE1Wi}|u{b_hY zT?Jrik0!>HXLT#X`_#pSqx+mosG@d`)vl~{iqsYQ(>UACMcY^7czj@Tw|0&gK-w8$ za3++u$h!Ri9Ci8)>2MJ>x1!-Cr=F^}wR&xdcCt{VhNG3A>7GSm0m1Hy8@s15cI z^?FizDUxP-`Tiz1xUwgJi7#Tmvew%A`Syd6^YwM=@#nYG<>B65FX%!lB-fb0(BPLw z<6O&J{oFxa>-Je#7xcJ;(eM5<*B-xi?8g#!4@{>KPhqcI_eYxFXddBO?C)L9nR*3T zb-(#{k`~IrMuYp|N6+on6?--xf#mN@tL8fVS>EZ(om1-IMPOJzihB$+59R_CzMu+L zm4mEEAHeH4ETG`_-Tn#K1)p4QS5^;@S`VPaNILXIpH=W&R}S+rE=hi*xI!hy@_P+* z?|wjsl7B+v-H949+HzZ9N7|4x`D_@eVfh`!{zq!Wcyg+!ofT(we8+@LYq)d^toraM?0WoYX&7TvLLDO+%vC4ft&HVH zMPEV7^n;0HF0-a)vgT#V`gkwZX#7rK?$r+G3+=Y}!xry%9 zuvm9db7|%|I@(Cn5Rg_c%5gfs(_qh33^DhPH~vkNbI|@0c{e@~U@#9or_!iG$gR|d z{uJ^;Baz}mNFVcd2m1$ePk}A$QjdN6-H}Lyn*?ShL-~Lr`dr4I1GYmiy?g|_+j_>% zyiDwiPZZ5qw|T+uNX{8=v`14`LZ>K|EGot@u{p&7YR22YR;8PT=ed)7snFa1F{Sb! zb|d{SbIHHWUu686^&B5U(5EyuCnT7_YLFn=P{QFiCrUeD*hC4TLNRjuUliX}u}l)% zTAUl4M|b!sXj~y$%t#QpzQG5kI8~HL5E`m);zWNw4>EFo+&&K3e8W;3>+9AAPUKQh z8xb7hZmhs8!7RZrr8|}$a_FTFa%^lG%4vM-(rsC`2<&hmPW6jEyi89O0efiEt%r^bl)C+yKvjq}qPa^L7_N_>Ro%3CdMl6=MCZc{0Y zt%4K)uHDfs2lh6)oyRy3oJwxIRg4vrpAYPRw3aYjxv<4|F{u|oelm1qCQbq=zf#(X zG3vo;CNON>ivoV{mCR{oKh*p6BX?T9uqn;$}@?X*7a@cGwE3RT{0DmZ!HoTSS04Rz*mVya7hce2jn$rNf?p6`(3%AUwE**$53U6>>1sDG^DYXxlEsviFq7t9HrqilOF5-(c$t?~(-e zll$`LQ1Qw8R9xu(hZlH-ZrI24{)j(GJCSDIFp*(^;(fJl_Q*)j4^64~u@r(cY%~NN ze5#o|6UIMq%A_WjX#4A_vSbUesr3uwG@4F_Qe%wU)I&=B zLx>{=>2~i&h(JZ5t=MDS$h)k;lj6Map?)c*8yY=7LkGt=TiQLATs?fd-+xV% zOdrtD^Ow@_`#&lTWdHNM`rnj>e~puhrVFw%;6uhHUaF|DpdkU(()X8{1X2a)JYiap zFEGJ;k~?427krwL15#XJk4V&v9y??nOCY8jfc;c z%fpIE_48}?&n%#?tj{ppFG_|gLUNuZF0n5f6_nm>$zPaWTvF}NE}iw0Ef5CYW}h_V z7}91ky)PxMC;oZx?rkhM9&|flK3?`PApS<6uPmS@ibYZ~f7mEBrH1!-*^^^k$;K^jsBRyWCVQ+Ywg+nEM~Gh^?l;k_hvd#1S&Q;}50 z2rfMAaN1G~C$rRC(axqA!xU+A+0*rooQbWd zOsF3Z^99yp3zg8eBJ9Z&josVA}j%Jnjus=pQ zqTO%9<-l~sg;awwjGt!)@?YS)$-HN~Lj$DX3xNs!wMx!Z9AKo3t}~`E@8c5YR8}Vc zNVb(U_MpavkimiK2@$U=(1ou-!N|$TERYjA`NfV}27rig@NhvE0YM9cR_`eWU03O2 zUCH>tQoIv=s>4GS*-7-cb&!AgR73)I)aq-L%MLq?`_Da7>$Zt64c%sDsN*l2I$xUI zr)OG}S?s^h*#lX$r9y|?feP`1usE7<=Nth+vDk`wmdpkNw_(^Wy76U@guU z(DS6(kpz9T4c!^vY!6=hn7rhcaTFWv3kN=#O?PYQat}8#BX2vyv}Agi^QhEtXY}Aj z>GPA34ovdLNl#7YP}~cR0&Q;2TE%6La@@>y7K31J>BkvbM3(_;Mt0igS@o;#j18S^ z&6&An6soRflyWgN#_~24NC= za-fEBCW#C?K&MMIMsQAc`%J`x2RFuR8R)nVv;(vyzZtO{cyj6cRXjR@$q%Lv5D7Ge z9TT>$(2oOY7%JXDo=;tr*P-(3*I-k*0ly*i4{py>lL#g^Q8B7(O0K8K%WZP)?d<-~ z@Y?QWb)vucf8yoxSyMH=533ssfuQ#F> zR(g?myEF)t3X)39+=^M{13EwEUe_VzQo?P9haD1%0mxBbvJnGA(GlF@6#BY&L)jSa zl_P=-+G~`K&%f61@Fbbxfq(gsbD;kd%_;dme_a1=RQ-Ql`}#NcYNcY&Kft6{I-8v> zENl^Z0f}7BbO9{7oK0yAex5ElMUK+<(78dKSt}gQWf>4w9!MHr_hayD`H)&1;XhpxlpdO^wg7bMtwZZzaE8rjev;LA0zsqXVDO8OHSnpRStlXgd+%y^U`@+0wUybCMZEJ{#3lJ|P?Sf{VA)+NTDPLF}o+&1sf%zeEp*SjlF^njK<%i=I9)#&#WMG2ma8=avx%{(_Z zb5VO@BJ$o9(xEgSjw9L0)d-h!G&`KL)rHAa#S9-MpI+97v5S7}Ab08tXDX_pLtAV(*8=x3x{ zD~-xD159hF9(o+VcGyT|vqZj2p2a?e%#{B6E$5OEP3~~b9oE1@0s_a}ibd1BNao<# zRFyLOdD%US-6tzH7E=}d=>rDU-VX)c78H%PvDyXXx<+6)A@r(*X6(bcB zio+tlB^IZb@Tn}8LwNnm(Op&nnace&nREYfGXF0f-OT@T?<;M6rHBwd9;)sv*(J$C zepBn_%GH32F@qThKoCoZVG?xEUMNJZUobCOg!&{wF7$)rd0npvNlQt+2}ab5a#PTM zKV5@8S6c=y*od@>0(4H($Q7+zcW?k#Pq@#Cz2J>hmr$3fE~h8(WPi#0^mG1 z9Rp#|i_EoHJg2PHE@a9Np8XcI8(qtdtnRfJ(c^k@H)yEnsRr3?97fW6tJ|nW2e=yx zakvaz*;N>}R= zbhKlE>8n~oX~%6O%c%kwL~m&{YA6fN9wm$qxz3T>zQPzeyr=v&Mt}9l^B^`2*s~ti zeaA=e26T6q!Nl8nQC40+|;2%>>F$r}scy7>j!V!E#g*6$av}nbm?< z-od?KF_@u~q!NoBXU7t4C~*Wv=>eSzXbna3NFfXE!viEqr)6TELON#E;2||qXJuW2 z9N($qOs?4nL_dEue4wzuV;SFH>6L{lws=z%ZuC=24BB!^Xh6z`47)Y)g5j%y^bm${ z-XQRPLg(&TAN#;R*W}-&_czvHMsoPP6v*}JGu;1`H)61IEwuO=Ws`r)8~vS_{Qt3- zQpsM=+ClHj-e+U|&p|F!(o{sI2k_(;DqH3PT0_vf&wdTt->Vo>H9B!5CF!XS-UN!f zFfvVVRJN1D@Q#t1cwU1)<G>|dMod|Y$9z7fw%HF;YE!ljl`DWpT;IDgewczM0Hb<64R_WFVqXHt57O5=ByvNeSwMEiscH zBKWnVUNnmk{ShZtKsN&03_!prm-Xgr<@M7=_dhi161#IJtT63I8tG{;xd`brbGxv> z)|vC2%TWS)xzt$9%8il)+Ro^IE)(1nokHL~u`A_ON%~?Q868k~-1(+SpI)UULA3r( zPrsBgn3>=nKyZn93-jlfi(BW~>6w zOQDk3;*i&)>rKJW=2x0)&b)xCBPD%0<#7*Wl_yx!dkFec@$B4$NJc&jIZWO}8P5pv ztqJ;lN+$v>i{{-P1pI?gU+0ax`r0nHm7L1`AT+=n4gfIDB$AMv)pyVK#-MnLM( zyQ&;d%KKh8Z}rs%N((3-HpUD#3~n(9aWVLQ-{k9J`N9z)MB-vnVq^GJ`V?GK z-2#FcuV8I-1o)JcBs7JEE0p=nB+<$SROlGL3&vVEtgd!8HZCSzmTxpyZxwSNO&AIY z_+H=GO}0K}d0ehcrFZ;!2sioa@A2Wj-u(b1=*mJJ?seiS>C=9Bdf zZ>yd12XOTd!85uNgQhM|&F90w(YZ$SfUA#xSr_|Nvvmn%>F$XYWf`2l+#XUFCg!|~ z!6_X5^Lj;ajQ0RVS^9e>MOhD95Io~+L@+$*9(hkH6z!*$09mo8f?)J$@u!4fNBsP( zo_cFfjb1x=b@$&`Q}iD&{!?u?TzkkcGVa$vU@6>$1fyl}ZFXTdW~fhu{si7vUw@!y zJIhV}8D~4`&*5GA{b$UzFyzm;YoqTbHS7RXF^wY>G1#WmFx*9|iD^)fi-MmGbLJNi zB|u*!6p0vHzFqljaRNA?v$$h{fw{9-p&RAy)VuMgu6fO%5{ggd3f8&xT!rsy-YjLR zfy>&wwyklc1S3#Op1@+LxHMt+$z`QHY769|zCQow_H4>ZA z=2w&4rX?Iyf=)OhP}C(Ix10LdkOtBAjE6t9`Sh{k`&}L);j~na;V&epG{HCXVf?W= zXxhlUi)!LX1@BX~U?tQv+$O-r?69Fq#c$o^p4>Z zd!za$J-Bs~6!F!>!|*XM|C>F?WtVqe@yEOZ6e<+o;Ds8k?R$W=9DRgqUaLp>X@12d zX0tN%zIJWkt*u2)tN>9Twl%AI^%RzBj62n1L4$7N)|N4`Qh~j; zqyQ8xPLh@Z+|QUSTX>JSL)fp{nnmW*GV8{l_4)q@^8F*c|RkO)b-!^K6TV z1xE>zRH!NE1|G`Q)+?y7C|^yLpCnnuI*WaMN>cI?*}Zu;#$FFKhT&RrlMc<98A6rB zQS3$C z#;MsCHcjY@#VfhD4|;L-3VIR?hD>{kWNAl%TTi3f)Q!#_x!sD;!SG5SOX5gkP5T`V zP3XsK9+C!WI4mt4*Ve0^8xsuFY1T?KpynQbM_kT32ZGGk&dBt=l(w!&&E2y_wjvDO zy{MQB*MsTIAjq{bviJ+S0P%YzV#e}EVc_^i zBv<07RD9OBjTub7Bl#|~BD8a&w8arR#!N%^6?iK3y@|TR_RO3V1ytl?P5=i{Z3jbf zc`5E-DQ~Z6;;7EsL3$~f8n!g#B9;15bwoqPEL48Dy>*Bp#x9y)7!kLGDI=~bAkPsd zqIAJG>kv>f%idQ%T)%;W9K{YnlS2tJ;e^o#dLIIE07iFL#$lgOFJ|)r!hkU>a&Hts zYq~8s>K+YM4-eIV-izNIRniWVoe!?^U93H{PM^INAM;1>fk2K5TdhDruFifQ|9Frp zV27m^fpP$eDa^bANrx$v*%VbfL7Zo{B#>d-X?9GOR+6|Dh(exb63S8p-j1#j6!QQ^ zQByphxJ3vHsQ<{9Dh(lk-`NQYT%aM@@@Tn9Eh@GOZWo-zHVP$K$d0=ZW)Ew*l0Ku) z6}O$aDGPCkFq*wH2ncNnVBm=7VmufFXrnSe_4#x=>$D zh*w)xml|b>!~V*B4RnPbGah1zYZAKRaBc* zXYefy9jm?5k^oIe$L=YR*Pj!qoE5DsiqJ43K88|FI)k{=Izpgmuha5ZL-iw)$H7Tf zzB`1ZIBgoESi%ujF4mTtN;u@mZ#h_Avq?g-aRyP3a3D+>bae-5jW7|i)h=ZOVx=_} zi5X(!{iPmpBt(~P#}DElDZcz?_6S*iGkgVvRY8bFz5^x9p7jq|5=p{fvm&-XKs-F| zfk$HPJ)usN%0Tu8;fD?`eq!Jxz;h5UduJnfKi# zY+;#X)h>D2w>>b-LkOW=nD(oEPn^SK%Do^aLg`MAGjX;&L9(jAaqOPI?9V0j6qS z@Zl$Lv&(ZqI9vf9+#;Swi2H{3`F7mG4@cj_RfDFqXL@C%gQmC_&1DrYlFJ|Y@nW;w z%Q&iDRoWSRrwFHH>}Nl_D@iTSL@InT)GiwrTBFM_Q)J*BXB;fF-;!&Q!d&1^EeS6F zY4*IetdVSh{Pryf`M-m~ztd3vmydm>e_=w!GxM*?kdGhD7lW137D85vm6%p_r7J3X zw1qhX`ozj~3OzpY6Dcwq<23c@zR@JaP#@RdJ-^QcBTf~}01z!vCygdE*1V6#m$I{e ze_QVH!h&9=J8#ot{ZnH%H>jLowcdNdWtNUgfm(*D6|^1$ZnR>gD-E`Wy$RNVHYaRP zy!VHtPbIv(3eIRL99$l7+KlbX(o;~a`wp~BgB?S~aM4#s-W4Z=p>07$+J20$qF}SbUGZ9E@-lHGR5q4aOv+R!DDX9@TXFlJkY` zZ$1}$R|)*M8!8gIn0jre4iy?QpII_CV)e9JslHSO&-9_&UNJf=RZ!=Bn5945YZA&9 ziD5_JrKvdN`3mAVk3j9F=_0xw)`OI)5!)q4W$bg5XtVn>HBpnutuENv(d*o(fZW zMLo8un3uuIuh6^$+4Zy1k>e@m*L7;gmVa+)lOSuV=*|OWi~uTM-51xbQFF-XIH5dX z0q95VBr7G2Gm-8NO2yR!6#J83ip)l*a_RZk9h6aacNJ z1+4;3S!8niMTqlrN`gM7SZMEwDO$*O@+lDUspSn)dMf%!&XZF57?Gy*i~Aj1b#@ta zVp@77b^0ZdX!lS;Rd3Sz&!{~7ccg=wubcWg$2SK&kgga#yRQkxczTDBvbPmOr_gy! zo`6(Iy83xSt5dupZHT)DT#&Z*!2K?oy=_jGtCr?ncRCnOmQ@-gpb}-z&MLRkSImUV z`_VH^ltGK{Oug(Y?v2bi`a&w9Nd~oLCdh&%{37Q87&L%J|A zW+|x7U=D$@c6MQy$iz<0i`nUPuc=pE{WtI`wDq^S&SoPcM?+h?cz$gs>0d8IyvtN2 zsxN+q>5pwh&9e$oP)dEPHGui_nZ2!ge-eujyK;GVjd3Jc!Jqd_AUSMkmu3m~ZrS=ohrKLrz{%C#nMG@8GJ zup@OE^Pu@D%=8DDaD(7dzeo3HykTGx42w7tu{wtSLJ~rGb5IK>KYxXI%&Ui~K3RV! zWR$@(l9ri*MtV;7M3Xc`yDH0npH7I?h4%be0jAV zTCMd2E+Oj7x!!qE1^t>olTpHo&bgpc{d@ll6Q{3#NbGN&i0zn%&yc7?ItC70_o`#r zKVyuEO!aHZh%3-{~bijfzQg*=My9Md7trFN|W>*#8 z40y9Q9J(Af7I;5D?pb}?O;P9rtHWxp?_tbK)=Za8SJh0^%*#0*y-!UwFsE9f0=D8p zQ6>6eNK_G7Ubw`C^bP!X)^q=~&E7}`QEFaPn%rybozzb{H?^flF3JpDATc{&OtJ_h znpQa`KPt-Sn4XRuYwZo_o-GTOLNmA6N!nqS}9(M9vj5iBJKelrvrDoV@ zytGQ8Q&3mEu_biH7svw!S6AAvuF33K^l@PVX1DAIfDu(OCLe|H7o5kHd%39v2Wm9b zaZP-Lve^!M#Uc~{>4af{LygxMsJ|r>lYnOuLkq|(Bm&b++yN&7XP{eqGTG*5FjgTB z;%`(PO5xPGo~6Ht&O^y3XaYa-l|J}|?vrU+DOA^MYmuJ=<;SdW>9|U;Aq(>j>@_k2 z$^n5hdRrJYcqkh^d{1!Cx5z%HjaPL5U^ml~7nL=WJvBUj%tV->#mCidXC!yy-EQT(PY zBRykl@=Co`r&y199x)t`mm1XXeeCx;PfNdq9F>8_l0A-cJYHsH5cIGlA8Mz9ha71? zDE1H0J4(1&-HOevCwR>xN1{!Nh1=WtKrKDFGAJ$O<;{rWQnu15IUg|#)4^=$_1#2h z6I3x`<*a|4I_9a{pqiqKIN4_jfo|Tp+f4*@;%y$=Ynv5LT*~M|2 zB{_?c(P#7`yHIowbg}*qyB4L-uXkgmLo;e5AZ5Z(yV#G!heX@ZalP6K#h^DRy&eSi zU?HFF@#pcw&I+gXXByCVj)zZduQx?ZmdzI-P6$?!@)`+uM)P);E5dt4|g!~nq)|uLk3*k<39i3U`u$k1#G^ckN;QB>VI>ve}~=w!7(jk zqp0U>^p{cf>r7i2N$I)SI640FJZCCt$|B1ne8`x!%b~_}CJo2fA2cYE!%xlGk z^&ugngCE3}sM;qkQTw-c;Ahaph;L@VeG=?sB*_!1_+M=g$5|P-v?d*W-akHoySeP4 zj0LCZ(17|nI=JJSK|#X_Kx&C&K|`s6r-^XTamV&Te-*=g5T&c4E7WqaN;VZHHwbED zn{hf;^j8~TH7QqC$f*rdKn87gScgrV_GHyGKWFia`D{|y8w9Vl%}@34)mC7U1o^Ru zqXX0hgqLAf12;-lD3UJBgTpab8l=m+;e~q+s)kqJ`1YS`m7U0&+6OxZARPe+Ig8Rx z0rMGVP@D#~Lx=@39*%%kY+))Mf8$xpPchmHXw~+FHfH>mvh=oeV{{9+I@8oDI&EsA z15y`~EH42Sl@g|PI zy-zyE4+Ew8T01R@DvQ{;ch=GpJ z_2R{)lZJtTRTr9-z<~jnerrYo6m8;J>pJ4Q*?W@*D!Y1^!{ZQHhO z+o-f{+qP}nw(UxO`8?e-Yo^z9e{ZbwCt|Jm6S2=e`@Z&t=L)I;6FIn{V3#7h3ECA} z%j7?Dh%n97Kc7$UmjM6V=OZ@HNW5Cjb;Vqfu(^OVrL+28BVoJ6eKs@j%%*0r@$EqM zYT@pV8RI+gqp7vW>5vTtbF-6#!VXmL{XC6F>q8QzjReaJAqY}qe;Xx`oA&<+6{k4L z9YCuz8w|eDOIj-ghTYG~4pwNzQB5m_f;*~&3hx+%}72Nw+MatqaefokZ1 zYSi8+y4Uo@tJk*lQvBAQ^8(^A$b~EHVBI^~!$Y(6l?w)A*BA4f6>cp?rr5vF_ls2C z+F@0tYu&}~*7Tr!hRyxrW_HAkoEr@S-I*UJY)&~7Z&|_bz348uy7de^I`@-i6E;Jv zL0b(>tmiLD!ZF;pB%x#dTaut#lBAK?9F8B^^C5azha!MC#&ICBaod8$THO|$hk9nU zZ9`u%{dM;(Nf^c!#fd`xmLzZk=+IsKElIeLup4{QC%Tx4T8-iNfO6JS2B;-udrtfv@EHYG&g=c!7UXe}9rQkV;`T&Z*qmavE}dsdPY9hg&X7;h>pM`hN-5R@9Wnu^Z9>hDf-+JIR3|1|_SWgffDviA8{Np$eYLEmrSx0L zNvZSpdE4tn?niQsh1Si!9cb4+!0>+S&2EM(Cmzl=a`ZLZjTdUh3m*>5&ZuVEhb$$} zVcu}`!2YoQ<@Vt17o4LE$4vwxk6mwMcGzGx_}Q1^UN@HOQlLEN)qsP(r#7dy?Vb=_ z*FoR(EoARyvh@2{s19TnP57|Qz&>*COSANQGh%hv^YXykSIZ6i7F_kV!=4n~=Tzu6 z$1Nzy=gGhq`)$(BJ4tT;`rd7n>$}>>OSk4b@NcJG8`tGfcu@a%I@GkluE_|FRQ@$u z%vgr@_(RrI{{gz<_(S&8@R=IU+bVXoE;L9{`gB6$_{@r#(T%+gB!tN#cD2}W9u)8w%>B+;Q^F+E3yql)q5Mb-^=83FRZW}F z!3Ms)?MRwy1hmZ{@}FXeENXuw!DD<@ok_O(Ci+fRMa zn|tV?ELA7aZ~m`y;HBIY{;P9#Ty9%%dOJS>#@9ye)hp5+)8d2(=wqjm25L_B9teK^ zbh}2;F34l!V~8_0HrNRdKs*452aiRKj*99vrRT3|A^k|7N9Z4#vT)Mj*RCE!T{6mu zZ|?rxHBG*&zn{AjvYu4atwq?WOY7!)517AAgZs>#q2kwqNgWFj=ZXKdovbTqs#%c8 zu~x8eZDwsTrhoH1n<+m7ltaig7JW)@MMQN5l|q)?^xl9R4n^E-$#mKGQ@n?VH!w$| zd1@jz5*&RRS+YErYJYW)%k=t2#BlXjrFnpL#6p#*L0cUHaI!VFSF;9fW6bqbQ1z2BboID_ zQ8-VgeD-O-XAGQk`=YQd%g35(FXa(d$Knpe4B$dBj{9Q;UstjDdp*lJSf(axrqD50 zrSb7PzBei~+C&cI*l2?ygI=sj_#^-vpdPL4ACs-+pTwVK1bf>fxZB{v5!NWas^a!<*oA+R3at$uJEWC62v{_5 zcS=c^8v4Z0wbk!Bgxl0a>gmlMWMWlAPTLAPTc8H4J^UK{E%}TokNs&#qUgn!C0OZ% zkSJ;aoGT@KCS|P@@g!UHQS$M84v5*lbmlKCB2H}g5W20bF8B6a0EI{rh^L6rJ2CB+YgGfjSc+jYsO~po*7v1*a(EYJDAk-ZP<6T=+2#o2yo| z`vn2n%aTXnJ|K^n0#J`dgY!mD%h~Ww$a#Q`uKs5h7RLP7(coOWPCHGB#X-%e835=$ zIG3QrPaZt{{i@kLt|1v(q17w!P%6puXi{Ort#Jv#r4ztW=QdIe-k6`phIE}BidOC> zHqXjwv0|H<`1VZ?GhOeERRRQ2_jM=q)+3>&*>Q!ZM1X>Wn1R_?{)P;1+Fmt8KViS^ zv`2)<+GYWRestO;^pL5urpcgOl2!&Ex(96K=WpSqDTeUaiNVS#9335?t-L-pG6hrQBr72|>GPWJ`Xrv#9EV+g^g z7j6^!G&=+h*K{d+>=(&-Cj0pXSn>7eV$jm{m^X9^p@$FD%Ju~%2}rl+G%M43CfzZb z;n3va7Ez;#;o50ge#>&|M4Pf+AXAxJcdtPTBUW`x3Clb{$$rEhsg)Dl0Uh+~cKGrI zXe_-yJkbAKu#oCi=Y)MIhiO>T)(t4_$cP)2-O9A2z8u7B@dU~s79+^N zF|+_XZDDl!)~B02Y#}}Rdyr{H|R$Ph|7)o#^AXfPj)cFJHmLXA=tR42^DHqqo(VUqaJdXK0DW;WUb4H z{gIwJM;s%Aj#S4W7ilmYgMUk8ZeWZDDPBm3MY(Iq+ zO9cC<R;H-9A-(BKB zE#5@^%M{Dg1f)1eoU|(gVjq#g9=?JN#Tk8HE^Oj~&m$5HCMi}`f$fUqZcSicE+EH? z^2O15&V9KpVmAiM{boy|jz7%}7weeU3;T7^%}MV*rw@r6+Vlk11|GxgTdj6RDxAAE2MU_Q+lj#^XME&%K#aH1n*&)lC)XM?wk zVSf_8t{8rGKE!@Xj~u-9o%U{UU5pZ4SbL7YrAN&hT`DT5Dq}hPs zi_`g*!xow+z}g$l;}3jWmCK&HH!92x&EBssgs2;jiu1PA3IfVP*+;3V5tt?9uK9*L zh>Jc{vmvujBG1(d1klN_&KJ*Qd#?|+goSb5>2enTdTq`XJIFaGbE=+h;g~A|QP`Zg z-++tntmZG^6UVUnc(~%_hv8I@DCuWP@~F13WYbd5-ho+Pl8?)zKs0HAy1ef7_=l5) zMJx)^1qUm(Ad?)MC)HV%no&0^yqJ6PuE!%Wj*HG%sSP~x8#=a z$tLKTM%+OKy9oz+Ap&@pu)nH4vHo^#csF{Ob;bTo1Znyktg%>zk=T11(X5Ghh8s@HIm0dn zz!yKjR~Q6_$&JfAP|>fc1|V)-aL;weLB8Fve$#Qs!5}(4)+}{xfl5gb%wgJ^Xnoyj zLtRCs9`A4mQc<0hCI>h9_i! zBMKX~6biD1l7p6oV9?@pWZH2{aWr(uqXa%AH&Ux{JR$MMY+vBW%w;5KbX49fAQ+-^ zQ6SG#dKdJO5|D>i+`VsTclv_Zx;7bH&(eKEHE}a2INx> z&~WjGjH2j0y!=fI8!#PKYGV9Hk{V3jErSMn!#RZ~Ox)Z4XF1!8GYo5`43R7wZU2E!f1v9%S?ZrkR3Tud*ujJg~J z6C%3P?6=?&wLmdS;^E}t1au5F=pu0Jd)X|Wy)B-#Es{43v`XPK;<_0^R?RpGwK)BP z?Szxw;LomcaxKONzW7t*o|W?8Ig=_kA`s}R;0WG=yTu0FV70!3!GDz--r1bQrHWxa@fAB? z|0tZtbg=(|`3v^eYB2F^g!}Qsh2$Tw_jlUT_v>F_Z_NK25HYa%+bfmk-{a*x|M`nj zHs4^1HJ^i5dkZ6bc_(XYJ$*}~e`4nfT7SjdaMf$6s!}Z6?V125f)WNb zhSIc2A5jZ3A~YmtU=M`>R|}V`3khynnq88Ss#8+5Ft|$nLWO$6_uQz?WT!F zVhKb!z;)K7->ru(Eij``VAjE*eW|PvK@Ybo9VpJ*MsDkGC&OEGPP%#Uu`ufv$+77Y zJ8QXNnkV7EMiyu5c;_R_)gb%M8@O$mRFW~NLp>bSjWI*a>+(JB5jGX`&C8X_~~d9KRlPg;@HxPov9$4_nA zj?PE>Z|@`_`i0NZxZOp@af6lDFUQ}RTj4S+90H&zLcGpVoUr$foE&s`M*PkrYZmYM;pIg4M|`Q}Al9!B3N-ceE4gh#;E2(e>$h_4mM~~|G#`n614P!J8>l`RMzqxz+ zWAkwH+bZPuwij#<*Gpvpx282emdx!DLx)=$iwYs9|McDLvFrUGs*_>Vmy>XBPck19 zBFo;zA6fVN<3BlRa)DKd*1UXKbap4hJKRE9bPgw%-(T7Sq&p~gF<*>-Z12UZxZYp> z=<0vF7JtF%!tH@|{p$arefVMVvt#NF7x-rXhc`lx%%2Nr9`B>!=?~ZV-2D`8Bhpbi zf_SO&B=*8XN+lI35I6Z^Z_3I8d-JJi3#d%Qpw5NKdrqEBRynz=x4rQE zkcO61s8m7Js1+fXrHOo!B4&PD3e74!EyWaB zEP)BQ7z*5+VEMaDh{mx~DWp|NA2Wb2W+)+;se?5!i-*W#SZH-(_CVwIRyRf;iH#+r!jd#2Ggixf?fA1C@Ul5yHn+9_)xKoB8I>^_t` zlM#c3OCsh*;U>zL9lriT3f=01M;hEbzwcNv>T z(lP2uJZ_6G-+5YLI@A-8q&&R15m#zN)lXT8TWqk@Q7ZQfI;*T}T5B$aY0>C%@3mQF z&N6jkt~C~`&8rurI9N-8xK?EX3BA2C$Wfe7U>~$xic_8fT$DjLOWz+cXT>(p373at zA8u-dHG~gcpacDA5)9;{g?b;Am3sfjReUWjZqltp2hqO&3tazHT*RoOx)hligro$Q zy`9*kItFaf)++L%V!t|dMS+x(m^K8(?w$ZFYIbqj!JW#e+r022b$=B(UA{4Sc5V(u zJQ8jrC6fRm7jjdC?dffBB{Gv|FQaK^2$jI@8TGC3p;Qhs9x6%1&=q?K37#tGWjhnF6zjZUNhSKoD}ECc>M_AQ|dNt zLl8yTDs5-6ZRyo4Bb+mNb|jyQJM*N-gE)nO?{3d!5#4Ld%KO>SHZcb?DI?OmqKR<* zYC}_jZFJjt!qu1?+#|dFjqW8xYv<5gGlhv^oJ+g;&Jh(A7i|^sT`3|XJ`X4&Cz`Rc z>Gmg1x)SN-MS1KYv!s#pkZhfrQgO$OPWT*Eoi2-9=b*DjBosdz*SJZ-{3Um#LnLaR z!%1%RD)+1N(|oix;|p%59j#}8Fmy|@`ghf_6M?qlB7D@Gh+K5VUt#rqEJV#+h_$Wr zddXNqQy!@a0oriVU6Xfs9)u4l)(&7xF zT{^Sopbf)oIKmQ#VD-ykj4yC_z{*b3hJv0lk~l;W-gsEmHp98%PIiP3Zu7;165UQN z0FDdd2mUJbi)&$4(Zu8qBg3m|c=l<3j(yqIThmrgQaqm}uo5N3}JWZ&jsOWr#K`occ1Wz>g~fJnE@i zlqvTjd^iNo?mL}7<1Se)op79g_Ku-Y>a2M zq8#MCOcC-`2otO zaZ$`+FmMiNl3IUdHwjD5*Y&nk6u}a;!;+HnNJ^dye^e;#w+1*N=}WsI--t(To;VUT$7$wVhJZB!g)|3< zG-ic7v9fEp8bW0D!0+_LW`%M~L|k_j9s)<+WDI(qTmWB3(cUo9ZCM_la~}WZjxdas zH2vkzyYRo<_WpH<{x_8E|C(t2br$}wlt%@tzx3JODB{%_#f8Ydq~!dIO&wUIegNh% zqH_hN_yyp&$>&8_+Rtg7Tu@))h*pSV?>|3D_b;&JdWLq0+Bu#tIymbY?)Q(IuYaK2 z_6g$?d;N4?ZyVy1%^dZinA$BvKdgDL^7H*xnT;}Qc%na?7aM@}qxot`H{`5%h=+M3HlG@{>-A_Pn79J>)isG6ogCw0PtI+0ZA9n}PgHrh4|GECg>-W&x$Ke6YjFKg7ku8rsA}-#m|^_@Rx@Gn+%uJJPwcE8d^wix! zd3G#`LN7~(6bEf`XCfh~y5M;SjP%NmCvQ&suK_?lr z{cSSrn8L5PbhjN=Ab0xR%}1DOc>9xzKe2O_7=;Rav2ui@ct@b)wDANGWJ{iUzR$xe z;}5hi$f?tzXWxBXzfLlY0*z!;4B8g4Sue-{z(qQf$<#FRY5_dx$yhpO^Sqb*s12>k zo39A6J)A;|l}q#EVcmoIwkgdON1{@O3-grvYWCw7G2+KtfRC%>yf=m35GmjNq4&?f z&VJCqLZ~X=%W&)eHHiOf+5Q_X_P;6H|6YfCVi_TS{cbgOp|_f6gq{gt*7dRCPj4a< zS!;+RUU!zLGLBDbFi*8E8f{8XrEOnl4)cQ`C*AYqg$Ifi07@)kgvb8{koU_EV#{^M zOJ|4b_1iM-;=*{|F#PFxoaG+-`eXaC^V#_AfC82iNVl*gW;OuSHRWKp-WvnwU>6Vl zct_9sEh8e(bs!qWGpjgS+*MMT3@7%cC4%h*fQB1yH=KU#hA4}3bX`X5r7ob@NO6Z^ z;tU;qdapd)`6V+#_&rPI^Ve=P zBf&UcP&QO62wV?B1vYc6rzfPne+T0?oWQ9Q5Po3>N;8l1voZ;)+Y#F@VZ z@KFPXJ7?}$sFgWo>7N@F0MpAe@T;?{GxKd^m`gB-5LrC8GF4q~k#XSMsII67VjE5J zU)i`&&e!Hu?PCZ=%5GNV9+XXZbQ2nL`aHDMiz`hD1~CFWvPOXWLszR_2V$(K>#u ztSzrE64Vf~Oz-ef#SzYi+VY9eVp*>aBtbr3oq-3vt$6^W7*{wyJ6h#s(qfkK_Mp0G z63=W%+Z4fLn}(2x2tzT<*8FAyBtk3fNBafZ-Yc7aXbV6S-fZTf2oamWd+?&iAq%v0 z)X%}t7UDE~tHAQ?TwcVErL%4^Ty3Ol=4vqaG*8xQWp2a3!LG$KpL!&@Ra#>+A!42$ za+0W*75wlq#BHUkZp)+xB|-pAwPXMoSYC7{sEM?g5ANI7GiSwUMg-NCekrGQE(vqJ zG@$S{_Hh4H5=v5{%fU%|LwDpIBo@jqT0K2GjiS4EC04Do|61!{`h#0{e zXrmxG)HDPoR~2sthi-tnWqs zh8w!gy7W0Fx~y9%JqiAs5l=FNyft4Gpy5lV*;hRN&*_9x3FuCxMFMroA!&-pAufhC z_Je`AkVgJmtd-vT!2Yw6#M_Ajus|3R)UiFsvGWLqcS*@dnpLWE*$4){_?8g?THV2-?6OapO^{os zWVO)5uA+qY1;~aD3b+z__XUuO%nA7^8q1X{;7(u<3_=Rs7R&woDdtQgBbMS(*C_Ah zdV3SiQWl}+@67d@3emF$p}ZzzQxv`yjMq&pisA|_GY!U{%%dV7*&HNRMAP7{3>NHd zlRCyzd3(7;Nki^$h&3y8f28?&U&!9byi4>-KakDPmF#SXkgh_#4XQto%jdal$2*DjvURwJtMn9hq6qjrw3gucP!V~l*gg}-XIBJ3Lk0VvS z(blZo@p9z>)amcX18&}j5lR3PgXi8Yu1G&Z&AX#38ESDix86ck6)O~CL12=WE)$Dk zv@k~yc+!w!)XpDzIX7q+YOolyM-f9=v9s*MW0Gpsn15Jk^-c3J&(47m<~Vf{h>o0t zn@u9mOW^WmBcnjlBnxGOu$05_;tox$}{%zqQ`Vh zb~2=FP8oHpHk7SjibNhtFElYMC8<%BgX;BXP+*A#vR;i>$?gg3u71?qw`l*KYeQVNulL?*q-B8PjxA!>cfxgTwprYkV3DIP=FBlRup zO4mfA#37znz&kLI-ul?i@Y1qWV^MXYG7j@jpH+&1eRw5PHs4*OOil*_47)siyFf?umZg$+GhLS@X=$VZ z9e}GcP>vuv)&t#O%^VWTrFbe)Rh@B%#mq?G+ByYAbe?*U+ieFG8pxe@!|EIKTTA1sE?(8VrNW%9$VMVr)qPUX@9*<#$sS%QuZW)Hl>=cdaH4ke8 zw;Ka-adW~+IVV1-9nRiD1z_yT>-9AoCd4;j)s7)a@VpHg(Azp;$pmy|KdU zd-vzjZk8%m9@~2dJa8TSPnrGlVM#%+fcGZN1zAmG^SZImhiU>y_Dj^fn}xPx+Jqle z4m+}$Lls`fWiop#aGJKv|3nIMM^X&3N+0{#9?50MO$&G6`T{HzBC}-*`n90cwZKpe z;8no0&SFwR0**wS);**b`N-D6ggy6I6}COB@1-9CCn1b5~}- zaV0BLX2RsDCQ{ zn0uZd``VKe-J_#Kka6WyJtS9VB6?G7JySF?$_DsU>V-ehKOR!5{}n8&F2bkaLb3_( zz7#Jq0%@-vCoWC}Clf~~qnG81fxL&V7;3_Wpwy0_BqJufSS7fa3SKr5EVHK&<%`Mb zRC1!d+~j;_HBuswZA^;amF%gDSZ%jJR$Jy_ZLX1mkiO=QX}}jc4Zo2bF4Mcq`3Gxq zQsiJT*!s04y)l^e=ycmHURBs?;f}yGWgzU6-VJ~vT6d8UE4@h-T_doKImz6 z4f#RSWR_{SQRrP~T8b6+{d?!PV!I`l0{Etrdar35+4T>lQ$yIg+|0MisTB8r3MBp& zw&(tTf$a%ptpCFA|8iBfG;%bOG;{cl-21Pzy-1l}>Ar76M*o#Hzmd@PP|%JVx?5e! zT>v^dv%a7EUREpx1y{`N8r)O#1%wN9S+*h&|XrbnbK@0lu@X zv4;yK6;sOW~KDq!CZz9`NpolXsCD;&Kw5DC5nMJr=P-}0ni3|?x6^$`MSI5Mcw!FBchH2iJ!l~fA~O7(I!)lA@CbX6}t`CTmIIxNSD z`+0Q%v%dpB>y0y(=hzOx`nx6ItD@V4f%rjp<&tfKsP7$&u>~id)FQ&MiCYXM;f>`V z@(=!wE_{rCB0l^6&Hjon{P%0Le-rKVZ_Z$ZfAQj-{+VoWQw zRA%NXE>E{7sBB+7AtRDJslMiLOjI!0g8@Ircn@!wU$mj{D6jDAFi72;%vp;5jE?e| z#NsQ2Kwp&Wf;oMP65fXG?D1rggl*l>pfZ}PhH`ylGipF=BaacAZ-^$m8jT+n3liic zY@gcx7N}J$ zJ`^C6Ov~faRS{;@tyH$MLeYMR!*+^O3v9yrpP^sm5m0RglML|8#=8qcDI5io00~6<>o5& zz;tX{0(Jxcu+~$-#YO7?_^94q9jBcDaS>hqKDfYXcd2B=PHAX*%OV}1X!?j~yii*1 z*99$<-7su`VggMD#`k|R?1V3`_3i=;HDCO!hW+PG2=}WZ;LbDjN`^;^+lrgy5a56T zJ3G78#0-zj<_=WD(>oAj@EY8$ln9I9;|DTMb~W>Dx8H!e7gby%4k{T)i36JZpmMhy9MjTB+W}hs&ym z`Ya|{A>bVy^Wdf#w=RT?fun27{rq=kYoszbq0u**@bn+i1m6GLAN~~t`zwso-dfL6 z^gC$W^1nJnrs7`?>_{1r@$BH%m~%1wr8zS{#4yep8XgD=uOP7(M_Dx$tl*0W${L;X8}m%jQB^P3HwV|l*wRMAATCJ$`IyV`sw_JN9>{m z-_uDeq7%0Z+iTFl{rcO8)4o3N%K5v-ebKt{$MA`hCh zYV6z$&NB|G-v`L!gKN~nP#BqVH?z|}#pU6AwBc}NT=k`?{Zn<=9^D{?Cf5hmSk3lk zu9qSxPq9>%tiNJfsl))?ozIf2+H4#|KrEbhq-qAdKjC*@`^LCDy4$+?y@L+1^K`By zMV7HTtLvmJTMHLI(-NNl`nT)GW(Y~>uT^hhdu`HckeA`K`Dif18=G`+`=+#1YazuYqkqAp_-s@(2-WkJc!CZ0X@ zv}cXFn9qcSLU!9l*mef@nBR<~!44Z=Oo#j3-aQXmB*&Ru>4pU@Uj|FY`iK3j^S&>X zk%6tbpxfzB)Mcvnasm7LSVW*UXxv5O_0K<^i~f?1gD8lKU*G`kuInsU-;zF?BCpCptOdo z*a>d%mlQ(dS{Eo8T4+^9flK$j`UZyJ;(*Pc3V1~(dQn*>C|ttgI(pgIf#8n|kx(h{Ta`spp4ue#ks8&M{Y9XDMYdCrCDL;=@k_jOu|c?! zr}vpj<75exu%_}f^GmoEf<5pFchvpsfW;+R(w*p2aCz0OeDg71NpnHE*F$(_oz?u| z!-E{l63KSSZl)r6bmlGoivtPTD>NikZv`D7b4chcscDSPb7cmpv81#xCYIb!Q5F#_ zNm8*t7oXg|2wLlvn0A5D2u=7Mm{IG2x2gh)PQi(aA&5&%#rBd5f_FYE9QNX&?QBHt z_IQ$;TEey@DkS{4D3yxD39du(Fy!ie{eCj@!@y+-WvNM(FRIlRb4{z*tyC9V19Ia{ z&G*WVQ@wSVB34tYo(&L+grOVdmvQ^WBG6p}lH^phaH%|WSW#sx*UItY#ri|gOjf7D zQNLpbD*A)O!`7oFd8Xx13!x7S*zsx(2>-NP7?X?HZY&AJsL67%kz?jBs479CA*|GP z);oC*Ia4Y(^jU*FpQ87%wF{kQE6hk$sPTh3i>>%NgRjp@E2Z!#sUGD7OdAvjXn#7< zz<^t}LbKKteaB;?xJaPsOIf|2Gg-#l!t*5EAigt(WQ(-~WJ|bWcZ2OggD2YszOwW1 z`5QJ#^`*Cv=i&k)MC}IzkYUBe7|9QX1ei?#-AaJl?B?{G4Z;)XL46yTO1vO%<(923 z3vnm_GJ>3;`zylhYxcJTU9t&uWU2)U6mx|<6TV|~!{(JACidm1V9pvhR0D(|1twpaFYZs|0gwrylDs(?Vc&ijJ}a27{4}?uVWbM;cZ=wcRk$=Sk)di_<@Af;I!clJpoli-FZc)cvRgZ3da6 zKcSrOR`6dPm^Z~8HGV>8WxsD6=$ZdE)14!ag_=}VHxR`3k1p_?Gu>wtY`~Bx+Ub^r z!euw30_;|eCh#F}ya8$pDRY9+Wx1+dOwxyaifgl0X{~Rb_C9&i?Y0mN++I>b)nW+j zN!$C*z(VoD6cQhm7`}9u69kF$ed!(I8LqX{~1QHZJBAYG~MiH@kA)s z(TvX?xo3*9+i%!#Kq@zf1e__PHf2w>3gpNhD@=DK0xd}y{5?uhR@hd$pxS20o+8*= zZT*s2RiSW4E?mx?Eq-TbrgcI_MwK1!_Eadzu?hKYQp-p_g1t>7W4yRW-$hB@T;1Ul zN2;Je+Wf4neW!JocUmL~0E-xhlS|Jn{o)4j$QmrnDK_FBX6u**cLz19o#V+Rfx7H~ zR`A<5=oWv^HMH)N{%{u=%@KF%=r@|uNxhut?Bsah;h`TjU)+)AhDCm?Ybzt_YG3s+ zvXZM1@T_TAV!&)k`Vg7&A!iS*Ghip(D+ps?v~A1a2Dwbmd~ z9*2YbX#*;Wm-~XwNy;)<9pfqFg^*|2bfL{%O+%^#u$i|UC>7F88~L_s`L_CnmidJ= z2Bc9Apf!txEtlAyH=ycmH?@{@jIR{vlR^3MPS-xE%Xz~@18wZhltFr!j$0;0AuXxo1+bay6KqM=|;$)ox_B%V^{S;rWAqUxlM{QfdpqZ9^i z+)MKt+xnG=o2xo=F7qNsl$4{6c20UpnS>XXJD$~OyZ`;1G0r)TIM&Zt#We0JoRJS- zWm$~Hm%F*{c^>GnI@I_zNUSJerwttW>u=~pK*jsy_M3IV_#ch({*7VTe?cez_b~oX z?nR~o-(T3tXAzaw8Z|&6iV)Bs{yNp1{!PK`fH0ugxzPMu4Tsq>CBx(t$_=X9jiFz! z>tCMY5jH~*QWe4OE2%8o-Zonv+aCX5Up&>S@Zw+!v93_=;9Q~BMo~FgXabDS?6O%)vyE9^y5n5&8Fai=O;LRJ00CRe$lH!197Hd(v=@80{zNr!BKd|-Z zvb4V?2G0%13izFI1!-yo`svjoirpGJ+Ed24yt5J)SXQ6j64D>jr7-+q@ag4>lPA1P zv7iEDOJU1h<5o&wBcW0*Dj2Gv{l$o)mCH1XuG}fMhSo%6DC3x&OMl5Ca9fE%?a8Qlu@@VjULsFmQk~wA zDf&2*luFxR+!?C(p&rjO(X=|PKq0yKCNe+%TSBOl3-czy7dzIJ6AY}XQGFqc#M|*2(qGKa#!{Nu`rtzK3ZRihDo+3rHbkqN4*Elbr7Y z6B9^CA&91K<$S1|{=oE-G7e*ypK9>Biav8xLFn2Y<;5weKfYMC>8{_#Io zM-W4+?4i%eFa|Avm2?g&W67YJlykuz+y}-#ofNaRo`d|Sbr&d#HQ^UmTuiMdUsWnA zGgOA~s$(F!dlr?S{UEeZ%`P`869Fx*f-SS_#mhV-!jXAU4d-(0nD>fhoA&=l+gE^9 zm34oE2uLfSv`BZC3W#)fr*t<+D4=vVBGQf0-5@0)NT+m5r-0;lt}${QVCJ3Y|DAc5 z=Z1IvR`0df-e(^v7rQ_rC}h?BC-631n+bzzjfI>+s#YFo*&^g7i*T{yWL~$22)!_j zgYxk`1Yt|d3~-rEALW@~2Rb*}IK)%yM;%CHy>wTy|~clKJgL?zW#;k-F|D?^N3x zb6Md*pc*CEe<)pnwbvNd$Go`@x5jKIXVZQIQ6yO!y-QF{n!&?}4V%?U%%nPUkB4B| zSTYmMhdV%)?yVUu@-Pj7K~(yh>=T;q$b`;50z6OsuHpK<(eARh0~|e_1-(x`oIYqD zsX3rWcdK&iDqiu5H=2A}F4%lz*k$A6hq9UE7ra^EC#n=-`3;e5Du)G2mGW+4t~Mfu zys3`h2VUyTVZAJ$efia`T}oy+(G4kaxWkbwKDI4e=(pa*lx1zBFAsasLa2sUYfxuD z*SS!t1WnF`^`}JnJ?}Ri9_x?U7<}w*;ierQkq})LUa-O%FtTO#xzv+CLB6@+nsW+5 zV!LpHWxkMZaQLf+>ovlOt)$;vd0g3FE--Sw-h=}VP&G*)l&w~z!y`(2&#iKX_6DEP zg5DN!iN&$^AY!7z@HGtdlPRV`Ilo0j*{F1@bc1>L!1tE2QizKVd_;m6wkP(fDy?^U zNkv@-ylXvfsReiYZ=GI`%TfN~G1(?7wB3|J(?hY~qa3@T$Rpl&zinw(2BA?`h=%+< z!TVQHHZR@>S(D2#bu--!WQZa3`r;h!WD>D>$8qqj#)^6e>1YQj1HQa-dW(J9T8tr; z3~3O;u42&2DbxJSxa=*#Tmgg%4WbN=q*#SWIq7TzsJK{(Z%&lqo#%Z90@_3)x0`5TlyJVzz z9nesoy|kPx4pCB88m@l6&{?qvDX36FCo|Rf`n`!Db<Z*HblC^#IG}RL}IDF%jsPXAd{RB-j#$YMaZz3)d5)T=T{Uz$+ ztf_YS^63aCIZ&b_A8qUCPkvngcpr|rende;AjZ{4r_H1JMq8v;(_o-@rC3%BZN{N} zSkZ)dbPjAe^WlnV;pkD%-Y`CMm8v;r`QC zYOZqbheLZQ=Wn=g4nIC9oGgFEAKJx;;O0`FJlWcZAJ9i4>K53`Af|~b)FWG(f-XNo z?@rMypX)qW1ex{m7Na|TUv`gR7en|U##>98{GboWdg!^|H|zD*=od5s<536L@vMKg z9{3Jg*%b++m z6A?828BdfcUaT`C1V8Kg&$5 z#dgeI8vZBx@(SXhZ%@5;IVi9yUprA~G!Gypi8>M86Q2y*cF6B6v6xF|G=m4u|1Ba< z>)wGx;pL7Fz3y0~Bez|*wfVfH5nY%tFiObC4~>3zaa&Z?$-4^j_3izE=EzOLhb0(x zoYMYIB)kaxUVAL>2_4Z*MD!N7)8ub8yE3dk%h@gM&MJrqe2egkd%`^Dv%WmCQy2+D)|b{qeiNcPUbQ9vx$< zvRac`!j!g(#f$@tyJ7rBvIrU)J+-|q#RjVwfi?1GiQf80>%>C#uLhE1XD96Vvy>vS zU~I^S&wGCD%8JMxbu+IOdyg?-({^gtWp$wE`#ZLme#chgN-B1d$F zq{`1T{KlsZ&skg+b}Qdq<8$1@N!LfQL=P>+Y$k~7pw)=E(29BbWA)$@>XAc4Hi*V` z@TUSoW3ry&4?=!^beCj>5PnsrZlCzY0g=%{Lh2j+UeV&-)QSMAubsJJ{ZqNJi(V5= zIhEot%DY3HGR&dPUB^snqN7o7Ma_OxXQ32T8@WIuUIFH+^m)mXrGM4_pv5I~+w;%% zeHGRPdKh5yd+}aUkBC!95hDtzo88tvo)A_L1b2qSb1Eew%B7#Hn8nIhl9Uh`$Xd<4 zx=&y=1?fQEG|cy5UTSJ)WU_;;sEFzGbasUeqH8nXk8nMrK%-gRt7Qy%ES)a4vCimd z46S-#TP-G|GiXYE{n>HNB0aSu*|wMpFBVcZ@B|@dhfnkdEj`1nt+w-)$&}?S`Hn{Q zP-oS;(EC^l!h;J96Z0;OBX?-bH@3WpILgrE^6T@R7+j{zC3R59?OSG%LN$h-x)a^n z?2J$Jw~smMr?v5~W2etnlN*U|9DNfxlR*CHNI>v&wH~>-`BN+ryD>$?o%o;#t_N%H zh(l_UL?-dQt%qOvN;oc4ztQ2;AKupOm((6FYYy)rmk4;e*8o4;`nFZcTz~bzmKZ58 z`?D{Z@LN0E==V`5gME-gmUwKK@y9ycUY?UCMtc%+LbC+34VQ_doXY| zH_s{zbwDKR%Vs5nKY`OlJ|9(M)j{uqpVk#^%qVWf9-rma*BQGe0I7)vOgA1 zW-+7@LnZvYgl_Itaf!Y)jVCb;u)R@T))0!($=WgcF0uW{cp52rzY&D%18Hf$PBS~6 zVuiHs^o|?+nQ~iZon}+l7usWIbm{r)>%Y{#KeMSw{gg&ERgQ8tG&y> z+#(s*dwxy`0*!QG_HE*$d)+U{vgq23dz(<5l)Yf*R|y`llQuR&I*|ya3hLU7H7Rbf zBptrZmT294id9R{sKe;gS66oJpw#yvF8wCnoA)MD8%R!)k!SZB_r;HiPTT6Za2(Wx zxCk0i5Rd)y&yrlp#5p`OkaUrbvs_0J$Bd^0VO((QB*luSGDuI6xWcC=`3bl%>RkvL znYbrTWxUSlx2QO9>RwPrl%&hrJsIoNEqkyfS1DOdX}|;xqMzy7=ZL_?B@bfASBc`fY?%duYL3@t_#g$B zp0Sfw=~Z#RF*XF&z_gQeL8Kse58jw%Z5XSd;zf67v%UXo=_j#=tJyhHp)KMMN7CDS z;TZTxYe%t&1F*`9Bwl>{8c~P^|HY12?ZjDP!;)(nEjo^8Ud_!1A=XX(Ua(&wrG%r( zz9FMa^P)8Ot4<#@{LY8a+o@#&Ci$ZEeWGz?wOe9B(KXthrBr7(i^bUQ+B3eH&r--q zem+pW7eLL51x2_L^T4YP=yB{qoN_VH&6Y3}MBzOQ#4d9l;nAJ$94xAm9Ld*uw# zrR;F`Opm~m0Bb$i#o?I-u#sMS2V3M{b>B3bg3-(}q%J_U9APwA9= z+|4>XE$GKQ2Q6rhk?B4zlOVird7_i9s_Ty0#JV`pt=$V_m~j z2Mp;5wnQhljWW4Vc%_e0+@fzXhh-vTU%izPeKjplvE?}@r{wUgzZjVe=5Q|EG$vda zX?0p!Zie0XowYo7mrrE@uAW&yx*h+x&_Ef1=qK6Jm(dpQ@>S}JXZARIAXP{N4n9h> zVeoXXm!VN-O0#hZ(p2LNsTva~eS6K9vX0aBiLb~mdY;V~g?@H7P++b0k#}V^zdWN? zMqTnlxChRnDeKE_@HDrACbc?^+ zf5MQuw_`c>WoDsViHhkv5?o6(^HMoEnv(t)Vu|J^VJ;68*nUP)8bvClG|7!8hH(%4 z*w=(V+Vt$VIz5h!{>)_ik)&xkb(vk}9YKMW0}OKv<$jcy>`*Ir>|lL<_7L8A33qCVVf96DOu3Gd>Uz6z575~7Sd9IhbkUhLVstRvz?dS zKTC;p=(ZW4%o1{DF#E-dIm+dqs5ZC*VT*=?D525+UmVPospiG}&O<|zF zVYBseJRvmF#?U8CIjKOOb#bI&ZhNG%ZwdkP#MXf*#yS`?T9&Sx@M)?;>K=Kl>SMQS zj6D?D6BK!aySbcHP1ndWOtzW%Z|iF?I8&ac?6_F5mVCf^^K3Hn0eiCB6E9Siq!E0b z)XLFL+d?QUp4M{iR&t8hcTD@Hr0kgO`S)AXnOQueqp1*-((15c8V_FTgtzscG3j)_ zmuVXl&{`Xt6tdZORf5N-oo0LM%U_PJsw{RI#g1ZJG3m8_?845|YhsBP*6gv!d3X%J zo)=s2f_>jqZ2Krn+Sk6Wvu|mhGX^OaLl`CPK~dlg?i`(~$qh#udkP1F$!4l`_l%6$ z(4#3%S3lu{XUn8hTz<(%)APzFThG~7g4uA1rU|LJBW_4j_Z7iH;bPQv6$FqXUA@UsJlOTrlcWn!?Me4XP6>!834dC%7nxhJINna1Hi`BSeV`QaleLd~zS3#*} zXGcl(lk1d0gtpgrkmvc80w7u-mmS$Zwi@4JDRR5kA8LiT(VI+dIWjF-LaIx`BWxr| zGz*_rn5wyL{$yM$ic>vUOxs10_e9!5=g|X#6=;-3zi&jRXm8P%oCFK#7l!O_on5E2 z=Q~D1^I6?w#qjhmS1HENL7Gm6i$z1YnRy?zHI$yP8IEt87;&Fb+YnoziHxt=um7N} zt$B8qUZ=i!Hgu|h*NGPbziusJ%Wf>mAaAhl!`mqbGz*LLualCz<8Jfiw-={bVN++=0*)-<1Qn=)7jj zkB+vNU;22F=s}61w1IjcnN+{!aY)$+#vY4A;xn#h?8g578Set(g&|4|BB{kH!qW#4 zr{t{9V%(<_4Wq9s@C8^($ws}v>^XccwS1R)oZ$|~gFC6G_(LHHd~N7yltZ-mI6GFj zX5E7fI6;D9DlMYU{FYLJ69!+MZtgFSl=RNuusLQ8F1DHa*x!+&N+q*-W_YhWAb+M{Lnt#EF`*HW$Vzr-x#1 zNafy+M2OCVMr-a)m*Vl5%H;}*n7TqZ>fmn<%|kVTVqNub;K*I8r5$cG*9oa z;%Lp%X2TCiBnM4D!PmxR5#eL@>I|0;&5pi*(_-Md0@q6x_NMy{lm=fki4WdBdmr*H zo^(f_8(CuZZPXIbZNz9-{_4UXYgw=Y&mbz5()ZQ`df;I|nV3#{={MRAwAMUtW8N3U z-m?x;?$Tp7oEcDW3`k7nd?J|+lhm9wV(udQWZ4GgV-=rl6#w#-=raZ;Z2@Xws9Wv! z*FVjExqVI1Qxw@pU7JiY-pTVUp?^u9@t)!HsZU8y3wo{OJO|s+k=5_X8X3BaxpsRN z^cq3Zh6%osu)(KNn9VyS)qdnht4NoQ9O`+?Mubk|BY_mz3jycX63J;9kF@XdX9=~1 zI~GfiwrI^q;@BTx2jSa7r3OIC*mXRYB5Xq2jOgY?41TwWD(Tr#aic=={S3}-a*Gm2 zZJXgCE7J%2gXWFoyOWL2oDv+5tPW?JEGFPXMc#i6!Mvc$gMa*zjlCn&LsMlw)(v>_X z5f7ZGh{`lLKbW3yFB{Yx-m!6HBie#_n$_9O?OXM(b>1(*qoOr1EVtc+&ar~|5f3)) zf`&Gwz>c6zT1A`{ZAl@Y@fxWYiD+>&ZE0E-`%W9@FEW^3Rp>whGBTqBAvvi?y zq0=BV;j+h}NUEJemJ=DKMXOrLR@P5J{uLqn>wJuQ6yM zN}#r13*%Sbdy(6Jb^;tt1bf3L+vQsb5(ESa-c`*4{{JxNBL+6>=^5DpM;4viw3jAp zW&*lno7J~Q)Y_~UQ&p8kK$XQ}t%SuaqIN{V+v!D@ zqkgLtp{ibA=yuzyU`W65HZpH!Lr%0#49j>vjiOSn#$F`Z#J7j;%QtwV@OenB# z=3!OO*M4y&=g!)5PnS2)%zHcPW%OqKPUCFHhqcpW?!A`;#Rfyyd9$@uW|WW2IeC@duTLTX1g)qVMXEJh+t57)X1 zh3yYC8pTs@b7&5qO1{FJ;bra0B5Sb3a>LqCVbZGz*wU9(x~|q5V9Y`}DV1R3@P60x zAngSnw9zx2+1*XIRH`=7s&YBZZP6*l5r`9EHONNvwV+m%UhMWb*ZJ*?8*}g(H(d5! z_G!rYn1-%WHYlYelc=Q$eU@xQ%zgerr<|K>$Bx1nGm&##DDRUXPkVEk#SJ|1nMN#H z`EB0<+K5J{bp$u{x8C3Q$~R!0xMseo^Kl`4Nlgq<7evS5GeaB7_Z%G-xEq}Bh8O%f zVlq>Z#_yW>EiY-?&MYQL<;Na`*pc-9t>4|)@Q`0c4(NI1T)86oKX!nBJ{T@eMjh~3 zbk6WR@fqX3;oxEgU^+)EujW^e;ZM%eqge3ZqTr5-v4Aqa#I=lR_H0j ziwFm@CV1$2_$sDFwT1ZS5B5(FzOA9xA)CK0@R&!X?icY;KvXZW{1n21FhrBhwEEDU zO=~9j&}r2Y%kVagL~Kxt2w7+9{DBB552?fxXrA_#E%qh+&4X7=LJncgh;LG8d98+m zd9X-PunGeg2zbqdYw_6BD?b-r`Vva6~`8^V43mCTnKAK*E2CX_EkR#7B9 z66j6Osz@6Xq-m_$C6IG}mKG))8h~ zsbRmFeUe%zfuo#?r1vTs%b&Z6u0H*UvEYU>&*NFD;idg;1Kme&=#HQ(#!g}9;w6n- z4P8XI2zehOC<)wUG3|}mL9gI}hfZmn&2w1{+= zgemEEuZ(S?|PEh4B&;s~Oj!mwv6k9~&Z$s`t6 zgAb%b=OyTFj(|}!G{iuK=9Bwsq#WEq8l!AN=gRRlX<596{N%P{P(P_WRmsMQwETNz zdWKuVV))fI3$YfR-#Xba&UQBNUqD7Re0nrTZ$=o56+U=7yjB^?2CLd)21<=Ziitj< z-kX$BiN41>7*UNW-%zvdv3ergXRF2@VOOhmg}^#{oB?|ClH+@s6AAAg*7~LTWtzC~ z!Wc6+CB}-gSF6reIx1H5xYa$|B1Xtz-*c|Q7R=2ckifl;EnmjjHL<6gQ%n+)YZLgm z)B2TK@P=8trfkb~80yJ_8X9)Xug7(729Kfdg{aGmz&!0j<`wR0f-?-1C`yUv%(Ps( zeI42>xX_{7nCXFVJ)C;}?zYNKOqnj`b7?czVcSN<>`+Q$&u8w$iMNFr9ZHQAEKDau zCHUUn%k93UMB;wWM>W)xdgDRi?TXrGR$u2imzuD9eequ0lARX{bG}O}v?d1Y{wc0* zk~4&^Z(StOq7hii^n*gp#eJehGN_d^e2b+6i3=IGV#avfJAO#PVCI{$LeQdju5oUg zVT%Rk!F_-309`9=sLv{$+RzEQR(M(0FrMUMwB21`+cdh9P>)(ZmgaVCF+T16?X1=s zGIlpv|I9i+7pYA=($K($b!2v`))T%=Wy6Ck<2Ji>RwyooKy3u$7Vg_}JZNt!=2JgRRip!0( zFc7-0>=JJ9?6ui#_9-0cx}0}-&pSjpq_G%tN3DdMyY429JK|J!m3v;B+~>e|4((bY z63g;_&yBdX#?HHf&?$?1)c$Jn-p5(Vo}H*Zbgyq~BsUIF4Zh(?+}WE&iiJg8xi*oy zF%vqR)~MuK%RJH0>Ov4YE0(f6PbQ>1|Ac_@J<-Vx#cWp%mF6`;a@7~f8#|Ci+t*Jd zLr>VbeXqYV@h(1NkcG@E$dhezh(D8gM!l2KqFn9LT_>+nr`Y5ye#V=7;6>>qnv7Dh z%-(w(pXKrxnoB#nR{7ZD!Epe|aTs&WV>k(hqftyfoD3~Z#EtICx@w(rv8;wKn100z z!*;$S#kyai-h7@}U3`n%Tr6f3KvuOyOBz<-*Ve@Dxo;U1DQrs{igxyWVNj2*tJ@Zc z=Zc?CQ@QvA$GcZoHnLolZvnQRB2^{P z`1oe5I4&Y7-8EDmIorqeTg#7yT5syM5krTtRu03e=}s!|JwQ$1_vEXG-IVqzN=iu{ z8NvJ1X}q_yaspL%iUQkU*cKF%xA9Z={Z zTplnhHX8zJ8+UWF&sncdEI>8s4vVAD9Uv2j0)Lll{vQ^wc%NF^SXiIG5gZ&;mYS?3;BpF(onDLODI~I@gjVNhY)jmVqdOO&*eiMe3NlTvc*jslhgY*ZR`3>INdEAUGeSqosRGKt713ACQkQF@}L~( zCd9R%9>p|3IncND@b+?0eaPA_M@&P@1tw;rEA}%Vm!q_pw28Zc|den)swk?pW;u9Xc_YU0{V5liq#!NQVbDf5D6{2TQ&Jme_!0orwb=RX6h7_!zAsbV z;=PV<7h|+JS3Ql1=X$t4Op=wT$zN&j3ROT*^|-7ADJHU@h?znE{`1{}WCHZHYK^fB z_Vf;3tqyk6Fr^J13FJg5MOkhR{N8oD0IR;Qn0tq&!_nqK^x8?Z^fgE5#H;Xw(OC&n z`ENDR#gR7{#$kWY6E2JP^*1wV>cf-d5xcLQ25lAUv)1Ov ztf$Ib`HBoVT&jfT;bTHcP;6WYsX^T0BDh}0qg*4*(0vc@C^ahiK zwoR;%{Wp|sn5tSSuSwV}uBt=_!I$^bj<*M4m1riYW0ERYq%QH|IxL{aZ=>sfsKqJf1M zqJJ&YZ_?<16Pd~|6xR50qn;SUJLC9N$lHp{)t+3fpS2uwDd8T}^>XcxU~LW=^o17j z9c)?-Ke`o$`>>-G3!3sd&I|N@duFHWWreM5H~hWaF%|Mpu_uwB-6@69Tj*KvK!Gt94L*HAvE)og{mE3EMpvW(c5E~Ul;hRb268_Ud1dTcZWIk*g58erLVldCNqwf&Q2_YtoVdw_V!qW#+P*O zC&{?CN)`*7rhM!4u@F$Bx`w zt@9S^d4Tf4blUG3+Go<`cNDvl)Xs_a_zF8IE%YlM43qMTFi$!pc=1W`<>;35Ue^6d0YdneY!`w+ zys^HH+JTl@h#WWrswoQmDTO`vM^i}kgEyrFieBan2L)S|5$e%;Ji_Ba>22UAD~O6D zHfqy`Hh7n1CP>Qe&YD}2z(*L)=}qGNx@Y{gGbElfMt9N_dYE(l9(=*u_BP*;uFl_0-Js_CB`8FBVZ+2hX*c z#9qcnVx>Qpbb>LK-@qmwzMD2d_*FtG!}E6jo8)k%U>z~JmPKoW#I%Mqt~tV#TML5W zT%Q}MjrIheFXcsXeHK*q=fX~-mRM>j;L?4Ow?R=DGNmqHB5=qU$>27gVR+3zG10oT z`s4l9PT1B(?&4`JwP3;4J?VtBJBgmuI@^d|(X59qP;0diN;>$7x4vyXD7hu0rr8GrKB2wm=0 zqk*t`a^Uo7I`ZT6QB-2RmhcYgWLmZDr?0e}pP1+dqww>h@b}RKfQJqG-$TtJ+m;~? z<$#yw)Beh*vG9fo$w#QxPaDdc(5JW`&5cWPRE>x1|QlP`VLFr-Zdo)K$E z&S?{e67}5m9YS+-H=t#?S4g+p+9MSF_AB2+0I^KKo{x&;9DG;xz{^&{FSlHpV3b5~ z?Ar$tI(3g&cbhu3=Dkd@hAh4~1Q&t)09vw0*BJ7&}Bh?A@1h^S^JKTRTkWH1|; zB$wl74$p5UPqM-*T^TTOxIc$SyhS@1%vIob`bP5jiQ(`QW!}?fzis>IT@;0!7c&&c z?QAb}G?hLa8!1eQ*UDxndk25(e4|fdce2cg6fEsmg0j6t_sL%d>&+o~P8>eT-A6!s zfAcYBnl9;cxZ<1*Q{u-rQ*}M{Q1@r=qw|ap+%z6}0nNYTMwf(kP(1mS%#}VU_+BSODK%edB zR8#gxx1vb6XvwZ*G}GwV+)O3>hWdxYM5J53=$=ybgKo|-x*2x5<8Z)Z?9bXTxM|3N zGr^^2;>N{wD6qHm)?4DAuUEXT0yeFkAWz-JE+U_<48%dE9<$Zd8L5XiA5kii)*&Ym zWXv7cQ(D_5?-qe^;lM?VkT~v1pH!44Om5nsynCaDe={;bw^v^&?+mK8pi64??PK~5 zdp%-1uZ?Fs8(SJeZ$9KM?^q_77|n1fGh1V3j*9GiYAxvo&^;^YCQ8B@Ta+fYC7ZLN zzA+L_o3cm77@c9Q(sWd>)Ed52ol}#cx)%68L=ozih_yYxLwO3SBl!_WC?(;D=d;Q`X(RVBoRt%7bfjmYyF=hFnft;pVLR(&)>`!OnwCP*)H_=SKAc`*X4 z$%1m3)hIun31aZ+3sJ=O*_oGQ)h#;H39j87sV+v==x7g?ZfA?FbxrlK7Rr^reA!vX z2a7=8#ncz32y~rnb}P|ql7|Vax~q4vvcDk>uIQi#Ngqe?boD%sr?$jr8usvpMRyl@ zL(#x-r%mJjs|v%<)2Nh={;bM7pD11KPgAG8@qTZmY*3z!mP;aMllxjXaLjrKZ5X3N zOzxpkt$5=j31uoQS_75|J+-7|xEBu=%Pd)(^Fp6B^1dfOnYerBM-wA9`i|rwP&Qxt z*$4YE;rY|g$SFAxC`us^n?0=xbeV(-J57K{5h-wth zEM(=;&&G1I^X3@@Ml`9=NblW&mqX{qOjI8&FsPy{RS$*i92%M= zE#UndL+xZ=4-foZ*t+Ze{Kt1v>J6Dmm+>_NUU)jJuavT8i$}c7bKD1cb;8bkyp4v% z*~ty$n8tY!l$U^hou%#Sjcb?`6f!Nk%|KKt({N z#lxe~zyR0fA2*9idUD@2{821?BCIgJ#*KT#3l#Voy2I#w%;uxdxY=wM)gl!aYy+tl ziqi~B8C6*^bw4mWl9<0O{bc5KssLLkQF2e>Ad%73h~(AcZPl_4>|#YMEJ-FzqXB9K z>Ke?FtocHDt7Mz!DaJ%E)uDV!c>-07^ae%_=^~Knv#~@-(cB9hj42}}BmX_r%@aat5d=;(WqiXc?vp~%rr^I*>&c8PR^9hchbBpqCMHNJ)cmMo<04n zJ^Ug#3K36N!D}>@X7_;`rn~{g z1dbtDZZwue(AEPNF*g6f_APAW#`@=_MuiJnZlfyvbnFo#i0XZ@7zmkmr1rTTHVQP6 zh~rvmMn3E~AG{G?@y!d|anF+)2qes--=&4Z%r-;v;k7Nz?POo$5%y-*A&`Vp&Qj?) z2%$yI*TWh_H7@HW(qXr29d^rMyxVve>-kn{fV11@;0#^dy1Rak2>x%aC0fZJ?!=98WngizAGIw$OA;rJsJ9J+H}GY_#p$Bh5=csE>(Ld+U*;LvDv+}-4h>fw^>otxfb^MU*vXX|K>M~(& zSu_`Gr^-e{V(`wmvO(OqA9h)l)4x7{^=+1u$)h)IlsXaawGUs3r=~~r;Ck+uTOEq+ z_ju!Ob_+&|_`TKOa5K|%=%4qR&IqLpx_@higPSSE@k3CI=8#%w95aj|jD{NqtKBV< zA&-0<>FASWDGZ3cu+(7$HE)9!GQ*vzWmJ)>Dw|qJf|o7AX^#^rEr5-fL7UHHJ)Cn) zl?rgD*V1qFKZzzPe!e-ae&clvA+DjGyF~@kP&6TK(_PLN%BV8{7#c(sua5Sf6 zFcTK#?$<;N_o=q{k0M$H6Cgj`su0Z6~3p+yulF{)X};x5yr&KR}{o!EWY={}mWSu6`LY9V3J~9hL!$W2f#6;zpX0pj>q5+G@=Qx!fG%}j`(4&D1-*3${ zyvISs2@KJrz;e~)rZxTlZ(3m;o8M-wiI4^@%(k4xkXB%JDWtFtybUxPNQFk>zL^70 zfO;QW#Hd(ilJ&J&rS%B=IxCqA8UC*DRz2{1XjB6mX%QbJujTqr9c!PCPm9VLozJ$u z;=F_%rc8dR%AcKV++n6O7@*9i-`Jpzu#dSdnHF~VpphrXr7pw_hO<7uKT>2B8CLyP z&769Ig2-Ck>?ve$s^eWc{jUW9SPD4tWHU;3X>?zYf_zYy;1uzob1|yiyAATy)A;&# z9dQvT@0;5U_+J~bnbE?83AGFJM&^R^mG#*nvu48dP_yW`Iide{*VEj(gwB?jpHM?| z0AYd!D$TPOQPTK5`!}j@Ylk?WYf^otdtz^R@h`7=`qT({slfPY8LZoVws35~OUSD2 zONz^UG;QNy|NLD?tq&9z76}t>C*4j~r|A1cG~`$`LsXh@B|$@RnkFR4c8{A?PLCU9 zRsHcu@rEv#+n?3n2;EGaL`H9xxJfLs2|G~s3@ z{f_~c9G!5FFW_7mDH=3ZHH$%GzTv0IPfpe_EuBPm+qtYvxr?S^JY<#sSfaL@4Ze00 z>L96UBo>7Q#?RYTjJ5H2fs4K9=7Z3k&gAtaIMLH6esX9u1fs8C24{^rIlA6W0RM_-hP8w=2rsK0{xVXb^SumPGJldE>>&I1|o6m0SS&%w^@|IEWK9qeRnpK6~=iE`il zFaDD{-B%8?96I@xc3(nHZr*x~V!{X^U@K5}1lmcdaI;OYF5Bul|FNV?x1<|B==lOx zVX-PGpZj@9h?&^gyLLJ{k-r_T?O;F*zcev3tmDU^t*{*Nq(W2)_C()&nryoJXJNQq@{Nox0fqxGALkIgAC-CmCpNex!2n+Db z%F&7ofGEI2{Fue>{*iKlcG9`48F>9G0blhi;CXiEuGMqD`jxiN|N776PT)9+a~C$C zqF=xYe8p=Hs96OLCc%iI1}4fOuo3q%QN%4k5zTM+*PXe< z{5qyuM%L#(|3^1dwPbgJ(=bFrpbc zmlHk5_Rpx{(X!Dy_vt?hgYGTG69wRP0e_(VAiuAd`j_MWB@8hiXlwGtA{|WJ^?C&RHsoL zBoB~gwZUjk{cDyz2Pl@Sc| zTxeVxdMogQ%5{LRY6GLF`fo(w6&BD>yDap;6$=LXV}JWaI{5L;?-|9P@|RZd>v95Y z@L~NKHo7+di4_UpnZdu8RW4P5$iWlqUI6zAE(C-wxC);CAK-!yzQ1_7)Du9SnG;KG zQ38185KvX{fpO&Q{+~EH=Lr|bH)|luNG9NWM?lH~a>cnT)%!mo{&Or`81v@~&jp7; zOFI|{2y9?D(>%u!1jLN*f8yyMUGsbk@Vs||Y%(&q&y5afCkj+2fN`@B^8bY!@agxT z>~yS4MV0^t^97OxkR8rlzLEclohu9mdPsmCcuDdjzAy15m}kgm07H_Xv~rFy2#672 zbovh|<(&6|2h;a2{?U&_o{Wex0=(z|F%BNzhSC3tpDR@L^Q)iHec5E@Yna62FTgZb zo$$|0PaXH4IQo@UE;9>gc=@IQNjLS$_+5d@| zzp3hiSuO~;bge>?8%TMzK#~yx1MbiLPr&C>-lYQ|dezOs4In^ffB?|~L-jBDPpIJT z2<{iZzPq>%0A<=<>bKX20CsKx5uyXe4qU~5Vh2q7;N1ND>T-7gF@*f&j$0w%3TeP3 zP7jPBtLp#6&@UZaR3-iT?rN4KLrK;BftFV~4g>^07)zxM|B0pZj&gBY=edJasSOk* z#ei7^z#xm;{}UvbSuV!Z80q}B3j`u3pnVN6Og~_f^M5{+Tw0WYV$()B-wzs)KMasx z7>pPA-v7i4nEaOpr^zUrr5F$m41fy2r}LSJUx_UO;2lB~nCaERO?f{@wq6}l|MBTR)-A62 zUu`r1IT3+4rvt-&HFG)kxrV`IRtI&Dx?Qe|#sOA;2>`Hw5tmx{ABg|xxcuEtAP<0c zME<%8kd6Uhz!Qelm;V8R_?$%ls52Al9@IyG*RcW4Ob#Yi{?Zkgdgf0rQx-^)D(PN2 zT7c>xKowkBe1L$LrJ=tyJ+Feeg}{2F6;Rab-|R84el^68e&_f9gYSL)v&8x=8d?sT zG6VwxGSxW&~`M_}MkFLfMw6=I^`NKVlK}hG`Upgj&0wYp` zUvLsYya@ybcp1`haygc)J!J z?Q*z3%yY3MD5Ee&34kPifF$5{sk!~HN&o2yR|guzXR5+50J0Hq1z9lVbzxi%`9DYd z<=!t|!-fhJq7ZihChmhVFoShD1Lv&wuiURZ^8Tx3z-WknD{Ihju15Lo@fX{S=iyqJ z1E9PdI0y(vF#Z(*k**qKevAOJT6TK6-)G$y(`Rf0&i4lV;V!^Acy^#8x|}|ELH0cX z{`%-2Lv^4;yh0ezl@K5mGnhnBWS1j?9Q=nwVp@(CPi>{NthLO3Zi4!ANRvt$$%L29{kCo=W#$Kr)kDyuma#$fdG~gm?Wh%m*ZUF+@O;4!mlsu zk%0F9q`~pUtpd7qLxg~!1mhx%?s6`^OZ#(O@nX+FB>Or)4bbxjB;*F8JIH)F-9Hl1 zpV{K_KvjHCAHM;>SO9R3!Qe<)FNgc(bw5+>uebl`glf{+{eu9~3Sc_$X`4ISzef9O zi2B#C(PoFJg@ACoz#n+=-u>Wm*grk{a39UD+ThPVQOB@2Wy6_^GmA6`xzWUwFF z1L}#3J>j6PZ$A}KmNcL&@C^T-`EUZ24Ykt50|o&9sldnw zo*0_Au7>%pAmZPt?xJ}cNJH|T%@{U-AfO35J(z|9d9FqPFMTdnlZ28cqZPov4N%ar zgHhMuyPEn>HGN+K{cVm*74-J zl;IwOiR2^nuaUklSpSz{woXoFEe?NH%iWY^bH1>AP1NLpFd(rT+Rfz8UF&m*d^C2XC-U_h;qO! z!94{*>S~B{F8QxK1$UQC0Gb3J%$@-?)CD>0r>*})xY$mbI`^E%0qS3YVuAJ)NJ= zMIiqD!IeD&dS92}2>=JQdsP$+57F)_ydUi+Fbfg?cqeB8n$(*c06RVH^sFy+$ey-2 z3DBu{;eeo0V8A-|R|5Y}4tZHc0uz|`vv!ozbFlq2rTwAj%O;i}TQ2D2mreqzwF3qM@Z#Yf zFekj+mf$k}=m}rlgU)NT^M(h!CIlGU!FR|S`Tlz(aYsHaTP;~V+pEDcVloSa0kJ@% z5IESB|5aeWz451u{{G-%_XGvry%&rTdjOC%5D(z%bdiDo3mA|){~p;OBfYp*lqU`J zhHl>Z6JRamDu4^}=EVTm+}|?f01t=)nknGbQ9|@p0Kg-}ES>^~aDaKk#Sm$R`W(Qb zA_PBR74W4yh4`x=E|B4S8OdX0u6tSiK_M3vy9MB=0j?$j7F*E?S7QB{?k^3gi)F+L z(isOjo)B<<^E#;Ht8jm)??*-Tb71@NhS$^x*y4OKm|69dVkKZRb--rerGaJ~O&1tusil8EM#YXEh~0A>ImC;Bd@0aSo`rdryjKkpdf z1vaVMT3G*;<-}zeK}q{J)4%FY5MYLLSlm9qY9#;)p3ESD9gY_yGZ51k1M+H_nrZ`g z%3KnWaWNm{DFG`V1EPV~&e~c37U}OYfMQ+1V)=m%K=~n%Ou%Om3pxLmGVu?~{?y&y zaX`9au+F&`4B&ujKky7$kpFLSE-=n-u*QE$^ZW!E}KnuMKP#2lFYAddLMF zAH4?HZUYn#o~ai9ff8uk0FjipH8QpNx2}%~#_V+Ih0Hz$DE^Jn|5w}9$3|6U@fT4m z>VQ~CF%k>w6f8DMDb|kyTgntEU{PqSSkZkBL!CIC)@cWXD7Zx%7DS~OgobGSLJA^& zRFKH3D7&^*1Q7)xuDA+FNn{Z$DC+L-%*-qIym!wVnz+M1(@FT9bI;d3_uO;u-97w^ zlm*DzTT!tc#8A>U$S5Vjia3L(eYHK_0cr|THa`5>AIqo{D$7eFL6*i# zW`u?;<+Es;7Syb&awul#U)z4zh5!04g2WgF!Z6;KL5gwUWO~rA9wc-Aq|XpYZ%_Zt z^W~@cxLp1*d#v_+Dl$GMVwP7R{3n`)^ysuXu%lz;{O}O`4j1Zs-1eeTQ}}pb_AAnCj`b9VOQph zbSK|qMywN(%6Foqt=E&}e)>9Ek6F|>7byUj+`Iyj5UmR=x#?DSG%=hwSl6!`K!1Vc zY`{JdSmj!`!$2IT9X-B<8pDeq8or$R`bH7h;?^=#9oMAq>uP)T`4_~|58!<2UpP(# zSGe{n-`zF*Udrn~F2yjKFmX;~@#8Zz>j^I5G$X;XIujked8MYN4ekfx%P~wIybeIL z0&#jw9J|B*dkdn$5RzuE{Rer#vG8*JaVqZ`0np{5oiRzIY3a>d6t1o@!!^NJ=q$Y7 zAE=_Ed(P1jrDO9K7Er5xRxcbqWTMSR^+p(7u{lGShY0fb)vMvv|pDrbztnGPV&E*h(Gt|y^&ECce zR}hTlGVxp|iD9iKc%aY6c9%fGCMPl@$v;PDO({K&%;h^&taF(j23L#t zici9h=pELC1v|}$V!)Aq9BA`k4782OrBpjdrV*_QMBtv3@CT+PG0+ipxziQ{y$Mp{ zmAs>KMGBUbEPZ&bA4<$}=RnA416#MBw;4jp0;wCBunuAG_so=ma!>(WKIZrF^2{`= zDx@d6t0Lmb#kdT_{lScA`aF>+Gi4_(X(e-5>WGh!ujWA|e5thd5fQhO^>}l-6Pd*H z+QgJq*(i(5zSz$3juj&E*wK@#%t&=$R3u`~(&IM!_v9Xg6kbAN!X;6LL^+B0gOK+1e+*YL84%OvcL|CMBMn*GN3-}gd;*def$^{;tFq+_2Gw3CEWUZmlj z&yG6O9kj4#V3XHF>qL5qyD#kvF?F@`{;#ENd8lr@m1@sxzj;-}wU5KeGO40{d2`Ed zsNoRQ%!?;8H;T}f-zrTAdi0u#{q+q9biIA{d2H>br09Ccz3bNnW)VRsp{zm*L(op9VvEg9)VU=s-NBFb-A`fapIHx^y(H^wgLDV@C2SwT$Gg*AD424t4+L*B(97@ua0jikD7oiJlkYQZK{P^*4A~IWU z@T5qp#G`bpd>YHN*#7tv4UTI3uH7#T+KSkiiQ)5Ys4v}tZo&;Ok?^SMSz$lL9&c%7 z1lQV4iiX3qd8n6lPTQ*WG#T#1Oa-ARpH!T-)F{*9IxZC_D2dr~PGMRp6d1+`cviB1 zx+|!C1e!(>!f#%%_m=JOo~CqrU|A9D3cizjGQXdebPQ~VASf~6+wyHuSM<0@P-UPm zG)aX5H7-XfXe5hn?e3)_Vh1F}6NUaWU1`}RMP?rr5}wE#kNhwLM3x}V=PMdEjP_Yw zB0>eHNZ1UGgl}eMe$Q7F{0iW5f9j9^Ig&PBNB{y!);Z0ClOXh zVou|Qw2e5p=HiLAF~kZYe;s_9j%zV5^qQGM6B@*D4flHw9g zRO*91+?5Y+aD`4xRPK*Ok>OZ^Cu*v!uTcLmCZp#{W2>fm-{9#dgHEe}P}RpQCNR|H zT|i}r2ZbkuR7W7n>RSs{jPj-Lo%wj&Df3f}3S+JZ^@uz5X8jQ3u4D86ojb8(ot7`^ zjqH50cjcBpiZgB7Cy7P9e7k~)<-8C7DB_~h?5)w~U{W)TZ}9KeGQ((S#T;b(4?|Ob AhyVZp diff --git a/android/lint.xml b/android/lint.xml deleted file mode 100644 index ee0eead5b..000000000 --- a/android/lint.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/android/proguard.cfg b/android/proguard.cfg deleted file mode 100644 index b1cdf17b5..000000000 --- a/android/proguard.cfg +++ /dev/null @@ -1,40 +0,0 @@ --optimizationpasses 5 --dontusemixedcaseclassnames --dontskipnonpubliclibraryclasses --dontpreverify --verbose --optimizations !code/simplification/arithmetic,!field/*,!class/merging/* - --keep public class * extends android.app.Activity --keep public class * extends android.app.Application --keep public class * extends android.app.Service --keep public class * extends android.content.BroadcastReceiver --keep public class * extends android.content.ContentProvider --keep public class * extends android.app.backup.BackupAgentHelper --keep public class * extends android.preference.Preference --keep public class com.android.vending.licensing.ILicensingService - --keepclasseswithmembernames class * { - native ; -} - --keepclasseswithmembers class * { - public (android.content.Context, android.util.AttributeSet); -} - --keepclasseswithmembers class * { - public (android.content.Context, android.util.AttributeSet, int); -} - --keepclassmembers class * extends android.app.Activity { - public void *(android.view.View); -} - --keepclassmembers enum * { - public static **[] values(); - public static ** valueOf(java.lang.String); -} - --keep class * implements android.os.Parcelable { - public static final android.os.Parcelable$Creator *; -} diff --git a/android/project.properties b/android/project.properties deleted file mode 100644 index 8202ea55f..000000000 --- a/android/project.properties +++ /dev/null @@ -1,14 +0,0 @@ -# This file is automatically generated by Android Tools. -# Do not modify this file -- YOUR CHANGES WILL BE ERASED! -# -# This file must be checked in Version Control Systems. -# -# To customize properties used by the Ant build system use, -# "ant.properties", and override values to adapt the script to your -# project structure. - -# Project target. -target=android-15 -android.library.reference.1=../ActionBarSherlock -android.library.reference.2=../TreeViewList -android.library.reference.3=../achartengine diff --git a/android/res/drawable-hdpi/arrow_down_float.png b/android/res/drawable-hdpi/arrow_down_float.png deleted file mode 100644 index 2466c8f6729d8eb80ca99b658f3331082e6b1ad5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 618 zcmV-w0+s!VP)*$d7yzg;enuXCWY#3Abb@p(0Awa`Io_9 z@Y$@pZnxXV>}s`GEWQtgLN8_|Znav6x~_kse9hzW_)DcyAsh~;{#V>=HV<;S++MHO z>rfs8K26ht<#Kr^8jb$*4(j##VJ4H=wJfWR;TOtRz+({bdcDh)N=1*wVr$citJUgJ zI-M?>rfFb!1}-?i1fGLe;7uS9_<+Qd;S|Aq*0EkZ^ewsg%77lY1l==4GMU`3)oR9F zI%Xd8S;uE+r=DnUc{S{ACY<` zcB#)>EwCU7D^kFY-lkG1z1!_xP|PdGoR|9>lD{bRO6+vV!S&|?e%k`C!B#e#{m4(6 zSB_;~iT$_4{86W(6CsmsNz$a?k!*Ed4zq#n4da8mmV@dW_%4UpNb3H5ydi%1M+qu^ zNReghO3n3!n{nbv$Eke>Y8P(lTFD0@Q_@>v#!mqT0EkT=)cWwEDF6Tf07*qoM6N<$ Ef{QaI-T(jq diff --git a/android/res/drawable-hdpi/arrow_up_float.png b/android/res/drawable-hdpi/arrow_up_float.png deleted file mode 100644 index d1301c3bdd0ad7292aa7fac5e2be9587df0a0c1e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 616 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 M107RzwYGE2zYr|yT>t<8 diff --git a/android/res/drawable-hdpi/ic_menu_archive.png b/android/res/drawable-hdpi/ic_menu_archive.png deleted file mode 100644 index e2d9bc1a3c96d1f3b42520c3b7a8419968489ade..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1094 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA0wn)(8}a}trX+877l!}s{b%+Ad7K3vk;OpT z1B~5HX4`=T%L*LRfizez!?|}o;S3DSex5FlArXh)PCuV79V&3#{_~%l<4cZkdSp6k zZV_eTa(c__7}_cS=m00@j?fP0orMlgj}F8isBaJ`cyNfZN{3zH$d;^?QH)uv8teg? zj|G-5G&Ic2UB7pCzJ*2Uo3HCS%_mOqdLA2=fB#(iGwb~4Zx6}te(Ni=j@|eF>wxVO z4zhe#JEECv&bQ{=XM_FASU65G#x0q#V_l-(?QXxOiLIONuHM`Ku73ZF@`Wzm4@;*1 zJn?&hZD`y|sX}EXGsYrwca!B-0oksH%8&b<(~(`2lG#6_@nz?ffCIcdN2jyjiJoj@ zXnHx!@WcdQ7)c&D!oyu<^ZUk`TZ#eGLnj><=xm!IaLV@G+fH-2Q*yj>=I_br)LzLj z*QI~v_D|^4-@NeTRoA~$v@Xr|)H$&5?`i>=pC2}Vyr$>;N4Wf@s%22Ve>tNx zUlOBQ(Cp}G*J}=`l}hN&l6lLp>Bog!-Litrwn)4Di07vtwD}qx4Z7;q>z*?Ie&w1| zHfJRo8Y~MRKmPRid+O2LwGPr%5w&Uk=T1&y>O(L-0A15*%vdo9;gZ5p6nmp(yBnw65o9v;$-jlF6+79 zIH$BbboU*>(=Pe{WUl;ueylK2>$`04KHeSQ{FVmy*)=p--d6hT#3#G2X}^w^`dl9#KEkC%GAozAt$@fTMB*Oy#VzPU}p1K*^XI*%`jX^-~^>_21%vT;LNtW0d=A8PJ z$Dy+MT=dP|F58XyD!iB19$%xh+(zr^EdhtB-~~#{U+HvsU4PHVB;#>1G+cd}!*2KE zd`v7)d}dGe4|{1jyNqXn#M+b7eb?=i`6gy`OKY3z1yUO_ zQmvAUQh^kMk%6J1u7RPhkwu7+k(G(Lm8r3=frXWU!4kislPDT;^HVa@DsgMLDtxLG xs6i5BLvVgtNqJ&XDuZK6ep0G}XKrG8YEWuoN@d~6R2!fo22WQ%mvv4FO#njD-yi@0 diff --git a/android/res/drawable-hdpi/ic_menu_download.png b/android/res/drawable-hdpi/ic_menu_download.png deleted file mode 100644 index 628028c7ad8acc36ff76cf2d3ac25c83a21ae01a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 909 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 Mogmshu?IX?8Yd{AVtm0RVvC9BpjRqU!hH zzGX_pm$fG^13KW8N31bocZd4=ZMN|Nu4+_E&U<8(FB+V1>i$0o?nhqcY_&3bGLUNpwN$TzRm z4@&f-2zNeJ4lrxR3LkZ-clMk{u^cWLb$vUzzvpDO|VT8)v~Pue)#P`rtComA>u^5 z-hU6;%P;BF#6KI&I&-_P`}k}shE1NZOJSE{9aPTd@?8Q>@U2~;3!_s>XNY=0`s;DC zf5TK?E?~$;w8%8kO9Zl|Cr5WmdH~V}_5_mFNrASUJ1O6BfkuTQIEYRjD`v6)SSNDT zBj#cbH&r1JmXXr2Q&a)(EGi(?rtuo0`tCWNcxTo8Ehy!IcFpmjNCpHdf7pt~@cK>B zu(@omJ8`j9VxYC!IJfzdj8yK@|zslb0%qbk*0tTh}#Xqsm znn;0)t~A&rF&;~T_15dX=;qA^Id+X}nlFZhvjJCGr!_Zha-CgJ2{UpiHi1u`n|)+? zYkJeV0)Fq7Na|!`ORV?}Y{uY2%5W#FZDz1!e3q317}9U@OT2`t0ONuZp(Gyawi1bFI9@MKDHo&=Wl>-rLeU7Vi8dKyk6s=&Az6 zkFKbCq2F^oA1q{&hNX|UptG0HCLkMJW`dRH))#oIrD=JA0UE-0OG)(7(qZ@ZIh+=( z<|lo6^ddAb!s?Bn64>B?Fxgel##z3BD9tu=s4~kl*A~G&PUh&E|FPm%*Vio`kvKk4 zMc9)4@!-)BBP(xxk(#(iul2$-&bjV&g>i8}TA_>`)o|qcvP!6Um`%fm-ldcsbLA%lsP@5(24;c%|!PX6xjrmgtyfs2}#p?L1_%n`qlF*uJWaul%2aZG%9P zi1PEsxFf-sdY`hQeV-+X<)G8TD1+Iu?XEjL4spHnw+<(tw!i|BfS^^Xf5V)!*`N%i zt#YJu21(`W4ZA25H$36dP3G%a;TOWl-WFf}@(bB`g}Ql=V)fuy;k6W#$geSs{*YPy z1>L=>(WK1mbeD?1&Kd&DO>B%QC|trnDzi)4 diff --git a/android/res/drawable-hdpi/ic_menu_save.png b/android/res/drawable-hdpi/ic_menu_save.png deleted file mode 100644 index 36fc7f4ddf1c1dd0af739132230e5faeb6402543..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1248 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA0wn)(8}a}trX+877l!}s{b%+Ad7K3vk;OpT z1B~5HX4`=T%L*LRfizez!?|}o;S3DSFFaiwLn02po$i|v6Do4N{`tP|YQ~-CmONYR zncX}!E84}!drcUZ>Z3&=-SWGgmOi+?t@N?dYdsh9by`{+?~Y8(_`s}kq;&~*@`}8k zkcm@n+%lVXY{t)u?{^<39XsRw>E7&_7g`svrxor@fA@aQf6MRp${*JME}yCJ+HLKg z+aF@gw>B5w$#!Ab^`-8+hW*lmFE4)oA}7rCie1#ytdzERpQ&~ zJ(F9fb8t#XTm8PFz_tz!#%>SCLJ3A5H>Go0yhq#?CNZ#kWF6M*>fqAo zIHn}PQ+Oo8LOs-%VT;kt58dZY1i548uWLJNdD%`uI?jF1*2A)z@*VC4vl)0>=1mm; zeP>=|{@R6`8MU%+EpV~W5fohE?Xu!P!@}1|J_pZ8%}ATwr9V$$nVrbw8$3)AN1tXe zCp64Gxbs2r`OBQ!mv0mC(^|zLs9M)kFk{IVSApw%3wREmF^=ax@LNG#%OA z&#BxiYJv$3%0?UY|NDzN^crt`yLeI1#KV_%c?U7JTZp`7<%w%rob_18XTQLvE}7{@ zKR5K}KlfuaoyNR)(H0X?b=TS6GksYiYV0nA*S-F{#@+k#;-xR{HcmgPwrt`oM^UlU zo1bplwqs^%O=I)b#y(Y{gKu_id6N~l%xBq-pij@`rk%@H==$?1=Z1Tk=o7c41&yn` zX2pkzzdUe4y8M3T;u7{294~o1GyKr4FAf(V5uf7JpX6aAv5%omcTYK9=lq+5YyB=jJt19p8^Ue7jaP z>Q7q+cdW{THtzXTs}8?W+Ap@p(&OBYwIY%KiY5nMycyDPIq#XSXwj{oZp=@9tv|27 z{Z>ZEuIJ(WIf096nh2kNr5Z>w8s%6aU;hsbFwjm-UTtL$W%DroyG|GV`Mg?ky-Zry*%9UDLQhsZyW@NstY}`DrEPiAAXljw$&`sS2LCiRr09sfj6-g(p*OfQlGAUHx3vIVCg! E0Q+??HUIzs diff --git a/android/res/drawable-hdpi/or_launcher.png b/android/res/drawable-hdpi/or_launcher.png deleted file mode 100644 index 22c526f3157a6fb8d337d49bd21a943b514e7f3c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9575 zcmV-tC79ZYP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L03_)E03_)FP$cL000007bV*G`2iyh? z6cz=e-w}NP0013nR9JLFZ*6U5Zgc_CX>@2HM@dakWG-a~001BW zNklxeg#btqG)a*#MVktl4n^1u zk|A+0!?Y}g7_k3HrWEo>n1ZZeNTDCLB-`Q-iZU$)O_3JC0R%A+Q;+DmtE#K&&F>DG zdCu9(Kk`;}Gc@p#f+Q;fry}d#%6jjmG0b`hSBK1qwD^??$#~(!$ZsNM$=5b2GV-PQ>Xr% zrSvDt?k?%zKxwrimqHgp_cf3JcmH-P&Wijx-b4+0IB+_zvAdo zqkBUC<&)d?m#)pODCZxw)#`FNIwCC=N^NVo@5%1`-=l}R@BjFxHtG<9frVh9uA+^q zXiY^JjcZ1g*>qGPwmHtsjz^kBfZbW>Z3#Vm6c6Od-tNwPA#rjG3HSByPww!)+>TBE^XpO|lq^ zFp@Qm7wT-OF2(DdV@!1wMx$}ii8J;OKmCGz$M_ZdUw-))xc`GcZ2wl6^sRsAKjoXA z_@q7Ep5TA@GhhD>LqAO0QkF}l)yi_$k^7#UGo5Q2!UTwzMJ!YzL=l2y0Ybo{IcDxa z9q|}kNHTM|+=B`hGVaB_lv2E8d3KK_XXWfA^nG@fTvG3vRKcGpTiW=4euba<=^xRb z{rEfWg`fG;`Zog7=uiK${osFmiIbmt%AOpbvLE^82PT!-pA4nEMa!j1+gfg0QrD4F zBIm57+jEjOuuwy&B&&o~!lIi6SBN5*V>rHj=gn~-W*~#g3+xO*7&BZ#y~O7{wn9?whPu@~#`gEG0_cQ*u@=g~RdrJt>|R zj13zJ8=Y=-bI+Sa_c-WV;%BA$B(3YY$ z7rLC)48CM8Rq3Re93Zql1o_{dNGZT{g$zfWIPkS>1gIs5P_XXpCL zG{x#1LNDUCJbL!gCWh~0)j{8z`hEZ>r2(i?ESJKUw;sA9<5ESsFs*dCOXs^ee&Vn5>wo2k^;HAu-6snpQy9n4B_3$Y@` z3n#~a4v6%<)c02UegG$DO3vh*S-S1o=BY<6R^8j1pobU5udI4)jGKzCOxSP7R6gSD znVN?$M>ZzLcoc~k8=Jw5JWF0?p`@$H`}a-8eY;8Q}Ux+d|6Ui z=HhkAxhgqF&k8vgb9XEBmQiM8zPnuTmRZe>ANXlr_?!RP?*c0RzR~&cm+Tup`a^c# zjbQU8SawB{BHmXY{r4Yu^zy0Ee@`i9i-j?tlNJlw#e#0RWVKq+wJmp=Q}cBGzITG& zGw-Xjdvk9R5vyk0UY@4+DHl%ETsuGFP1iQqnl_Bb71d@Bt{^tfkrHGVFDN$0w*9K}9(k?RRPF7sI7#UY$Rz*exJQ}$K+8+7> z9mbe&E<`(5SMA%z`^(R~a;N-U>iu@{d{A-5!~~<;Imt|^}Y|i znP2!ve-I{3f6kh}{Be6^f8UxS>r{mpst8`o>iP#hbpG07SEv7zL8R-j`P_W5pkFL# zS1Y>ZlCJAmwJo2!^lm%!4UXCoRm_A4riw`oC#J@19Eg>;u^0HlOOYG`Uw5_Ufm4y$ zD9}`aP#H2~o{XIZEZn$t1oM@%F%7ucw5hn(#Pry~qTB5{9eGZ888!};j7##8kxLG; zlIi+NXI8I~9{(ZkeEye=(j60|@Mnzg|8Xu~eZt;yYi5TN3jvERtFTyOHu|&QcK**# zNAYna*>Y*j=lB|+cC}))TG6&Gx2@*+i*KV-gIr9;0vXvNt5h+qAw+03;;9>Bb`A{( zHm1f`ZaJTRzUPS>&QTGa0^3XDxgGJPmolGwCiDDFXp5LMP&F2s+D_7?_uSduE5*Z& zk_%pna?UEbP&~W5$g|5`xMihf#rX>d-1Kjteen}^ym0fsq3JjNus!&hDZ3kPt`HE> zOck!?BcJ@=FP-|4AOBvg!Adc@4su3!Lo8=XDR?P7vvHY4?s0cQ6Ita*RR>CG*ja3` z%;L;ePhHpS%mbwuH+RH8{_R9G$K8p+`Sg>{Xe3U}3OBZ$+k1(&bzJb`Yk}D)(o~Ue zc%t!&k~L#7ZgQD?Z`O$>YhLHfw%JM&%Q^;W75Z7 zv-@8-e=Z z@8(W-nVo|(9L!I!ceF*PF(pnpT8=q=T7+2hr57jkDUgdO8CIQ`w_@2ki`H4J3d^pr zHG-6#mu@DyUeqyhX={OU&-Q`w+;wr~bS4A~rCq)0@bK`Ih|jo}byYktN$$fTsVYTB zrPc%8tD3*}yN;K*>+qC4ytrt4GY?S&Cqxq!MvZKAq3*xQ{?=cw?1SHEjK+`>ykXlf zIpY$~afas(-b&lmND;{hCJv59_@QBl*LEwWBau?1xR3`NkyOxnV>UrFXnW@~M}?9L zASR=ptEZ3H2uHNuGuo`Ubu{Ct*8&$d164DQXHKLK-Pu1{nT`Igmr_hBxEG{iPLazc z_o|k*=OaD-&`Za20Ur9w8M@e7$pmCkP)TZBHlFm$*`{}og{Qt8_>2D)<>@EE0x;wf zEFg^C-Cce;JfyN}MHTa9#jTwhH={5lX8~gUC?ft<-^Fwy->~h$*>?WdD@x$HX=$r9!Lh_klifasN%%}{D zQ5I4YZ1l?B@p94?itSji+G23`XhsEA1EU}N+)sZXc-o|H(9iuW%NL)cd)MQXv*+3G zI(GKd3eeS~L4w2ayt+>6tftlzt z+&;)CS0t}6Wn>1*q;|=n3Pn!eCRA)xEPQvnSiZV3X+CRG1`;SC70e2fCYZmLX60BQ z^;22!5KxX_(G+XY2xI*4-gAFAjzP_ z0j$A+HCO{s!#N>e+gzr5=S;&l7!V_@mXW3@giU8Ob-I<&s$vwT6!mmoLv$(?Pz$k8 zda>vo6+trk%qf?DPwLY3x{hstPS6{cG0(_~Sq!5(`>{Ye^vXt-qNsvdRf$p?VPr5l zz1n$u<)xO3rJQ9|u`15d_H7Q_IdXCHq3>jI@m;VEox8kPUpr=oNdseoaKC$=fnoRT zF++moBC@sVK*jlU2_-Qdb(lN1w;MtfThorlmZZL;a>FXGwl%Kf*F z;`r}bpfy=9=uMUgo&p{t91o;uy~!FwM1tn` z#EnP3n>0N?1k4+VbeA2rM#SzS5`<*ngK@;&aI}GRA&9Ms)0lJaObhCWxsZD?K5gWj z8Cg#$PHPZ);cjfykya54jx6Azs+T1{zD(_JZ#1KY87-y;ETNE06j6?slS~#AN{EDr za)reTG@IkBQ3wK;?uDa( zrYW4;oKxI5m^XyWSWmWR)E#9-_$GKwqOwot23x#&_NOH3-m ztq_73*OA^M$qYBcqA{xsFA-IR=n)i&=I=D}Z<TG+&cem?p*uuy-+c6_pc!#n-Rhqs4#>PGAMd| zXOpqfh-;@Zr^jO47}Hqz%684I!x528w9JXwimn&2S~88ssw)H_x~LQ&3_y)7P%PlN zf+V1#l3!ENBf!&Uj6gLa;=~v@9+QS^@fgSvh1!BO@3{TNhhjfJJ9ph<&tjdImTP9c zcKHL$&%BMGLCwhQjjy>5HxUEGI0(zTi7ID^>rJlDu(N15J<8O;(>EvFI2f^52`EgO zmar~a4y}VxPbz{Ux;!R?;Rn`1jAEp&0y%Z$Ak52Ja+I$_`lQ35K`pb&0s-uJIjK@I zEC!=g;I$FzE4$A>9QygGL&5SMd$^a2_D(#&&4)gMnUKPo73+|)fiY&UvnhlDED(;U zqX>xExNvDJaeh{~u|H;KF7{W>(Xx<>s7%NsclIZonXTA8+{89^*{Hz1;)&NzvQaOo ztDXx@hnw-re99~|Y}IonE~Lz2)juTJg%HBa5NeZ0hArfHOcEtT6wN|3v+BaZYa0_= z-M?r?ELN*~JK92`l~@707v9DE;(PESY|Rj9*tzTt;>ZRyIRFM!u`sF}&*J2y@Se+w zS>4k_m|d%xx0!>LbL#+}ywUU8o^iOWF$?TSoEWdjsbb~M!Ls3K71=$U5G~>-CtRJa zI7}56x5OwkEOH{77?11Ihzou8F{lD6p(t5Ao&-R_%+2Ig2v&Xjsn=Sg$W53VGC>%&_+SPORz%%o&Q4n1dOmZ01E!VHSiyj1 z6bY3xo*0{(6&FueTsi5yw%hUR&jseK=u_nSYC@j%Ec#7Oj#j+++#a*ga^tXOcQNJs zctK#vi~D2VdCuvAQ(V-DDuf3zOkHY(BExTaObKAwj1bs^c?WJWRbmh(#nP7G`1U5<`BBDzX_v89WZa?vsy>Gv0%fDc&?rK@gE5G?FZM&kiz)E6O3bRMv z&i?jomhb-vq$5H&4P{-u%dlWLM!*;_5)sifg-7pO@&0Q|q7|l1U|a{P3Ic|OK!_q0 zkqXq&i3pQ(@wD;yLlwXJ<;?ccP}1xyCPd4;v^%BmmfU|LVKSz5&B9?E#I2OsSvXsv zATRV;5I7|?MT!~{X~2%jq^(-<>L~r!>dKX@f_Ar+Z{4t#q2OuPY`XvJ-o?qylf3r! z_v58!)bw=Snmr-F`ki*OfydHNB7~0nPbEf`XewjcL_!!!7&oZnU@Uk7rGbwj7t$(U*eU=~Isr zPX-wI8X$9-W5-L}Kl0$=AHvHO4Mx7Svu*j-En4of$QfO}!u0eRPG7jlJA8*i z$79mPI(@H7!E;8drRAH~wdyyWhZk z5R!h+^l*X-r)GtBT!t6|0Tx)aC4`ySvebZz=AU#8yiiN%J@WgN-lh&45nDhyxcPM;kw8oDa$lB=E=lA|o#3srO~b7B-W8f3+zmyOFC zf%YgfYK*FKN)6Sx;$XL8Lmj0!(Ts6ZK@7HNGsWGcb>7r5nA9y6e;h9-bILbX-oI4q z^Hb%U?_9ajhJi&VA9*{ojSZ@%A=EW{R6LnR)X~@)MaE;Xn6K%;U7QBdxH}hzZAVa{ zPl4DOXSX&8Ho?LGWJ-=CB2YymRz`?J=(&Wc5Tb)Sl4BBe5Or{(#1~%`@4VDA2_h#) z!MME)6oWbqjS6cFNyS~t1xW%4UyG)Hxsa6JyXwo|dtp`o!aq&v#UFdeS3Z7vv*PF< zWOi>BJl33i(?e`*ZW5{r#fm5ThD9ng6h=)?pkOjw;hu~f+(@x|;2gHXt!0t}Rd2XM zKPhaC8|r9ySwku)86u+E9A3*^w1K&v^@EBB)U#EqO|CRFO&D4ydR^)L3)kEJ)SvnyDnjn(tJ~*Cb>0jSPCZ=njz2!; z(jUIa=QkdtuNz|1@cFi4FZ(*<6jWB6812!FG6N+tct$>4O!2~VHzKPfRw^Vftooj| z>p3`@b8CN>oufk*tB$_Q$b@iG$>dTBA@S1`Z zCROI*NvCO?RTg*VfqAmsR9N*zxp()z$Wt~QYj+EdHmW(N#(U?&xI{|^N!Tj$^h%J7CQ zTW5PAiW@Gm$o6U_pPS@B8QPYvV-8Fd1+s^xA5}G`<=|3lA)Y>X&`Y%Nq*vq}(PpP2 zGAd9N;bl;>7sp3T&l*qO+@j9`_aQqK7e(;QtDEc|HJsV#IkmYUSmLNHY&1?Cj8$jU z(HK`XGDoGbF&Z(hBhf_hLKC2=d>HZRGpSGXUFPh#XTCD_=80w|`jk0ZBwo5xxOFgy zT?Hc-t{Ym&l?IShq+@#AhPzquyj*Qrg5Uvb;l|#qe_?UoN~3b3i-q6njIF7d1*Zx| zEvI)F10!WlH7m|-HoUq!UTd|rSS(^*V7Y3z9&2XfhLamT(+Fobdrr(&1QLymBP}s= z%#8h`BjS4Mql$rPRWTg}3@3G&gPjFOM=d4yR2DgC3mZp;?fsS~u4kUSp>=r_=tVzK zdp#9eAh}c|IW9k@Rg!!|dsc=1tb!3*@Lt^5J^9-1YPK5Fo}kHi2$Uk40Cj-qft*D2 zfI?w9?znn#$<91-w5rzaqxCjk1}Sa^%eG>BKVraSRP&bmIxcJ_mde8nfjgB2qC}f| z#vx*ejZw|03aAvk&FtM-(5^bN7p{&f4h~ul55+Uv&aM5yq|@3%m-{PT%I#9rAtgy! zsBqkFN#&;E$|Wh_Lp8r#O3&Xp_w;UR$`PlT z_1uyvcVh!<~<==+x0q(x*#h@3OAKyt@ijDk3vi^hzQ9B(s6Z4WL; znaz;-@_uB$O>|wxix295-6$&)Y5A$6eTP;$SI|e-6?mc z209Fh4=`sqUz8I+%@Z24?)t$#g8A*q;s4Hs``>YJ8``^cy%fjaWEHq+8heUk+Z!Vb2JZ>lGg>Uq1S18SK4#86d2mw zcS{UsR=1pL+Cg`D#)~MWtU=8n$5bdmbb==M&=o0#;DwP4mBOos@cb^X_tj+(m{;_l zL4KzU25T?TOB6GFNF2xdz*_I!<}~{xJb&jPaIhbFZNKhgSY*eSGJCdLrKjtt$1Pf1 zbv3W;PYG7j)G$vI`o63ijkfNZ+?$s8XF*y&H#t~g*#bFmay;xthb~$~&IKr#9Jzyu z-b9dSf>9C4?yUOEjl;kTyO8o5dgsB2QXeIT6ER=JSZ^mPS)HYI?Znx-IFva#U zxYzU2Fd!l99#Dn06{Q#B%E|6*BC;|@0SzM3O2J}ee_1h$nQ_&!5d(Wm@s-V~#2 z<>Jq{wBLGtz3=>=Y_IHlig`oKLw`RM2-V)65Rvm?w{f0I)ST@yF?c< zWtdvRN*;i5QBuM3PYr&Vhz*SSML8 zkzMjJ^6QNsZyfOPcYPonP}Aj6I+b6X82)W82%dDLlfQM8Pqf*w?5tKR-$=!-N^bYU zNkf9Q^#vnG6wDo|4ClPO{(tM|wyyOy>Yg+85vGpfnbf5rq!1}3)I0N4AZo=VWOB(| z->m8+$kq;APexW-aNYn59u$|o* zaWib_YI&ls>Ao$Poe1U+Hd=l8rToydxfnTPF_b%fmoF8g6EHxHOL3z8>RITPIJQfAp@axYSHj6zVxJ+a>g?i@6uNq!V@*oV!5W1#QiyfkgvAx(D8nj8Bex-gfSgX>&+d zdU7eaXG(IGB~f`Mcp;K8^>kjyp4go?%vbfjF+%JOlXBR0hiRAROIo7rN8S zlp3k*S?%5Fh4{pqk2lAipSWN<-}10MvUi6&`LynfFT65h`H-1CVo+_^{&#G#^W083 z^XjUMlDm5h<@ucQHFurFi*c7lZ)B4D8o1X(?k=;;GbfwG11Ed7Motq%MWLc#mWe)W z?_tfpJ`crpPR8MCOwN%QeC=NaY#3X)Gs<^d8RWs_NO`S)@*1oHoeJxc@{Co{3@TT9`XtGC2>xwVkuKs@ZMF>@O!o zgHzKL$pc6I6e+HPrB9FY?VmCHhOlje16NqcedVY{)l zc-Pr_=ly5u-3QOsyG=vex22BRsc_j)n!EuZ-32ItXH1!`s^|Q;qY9$<;5PPMqU#cU zFP2?ocU5uya7LdirgdS~IQ!k0!**H>-K@0ug}UtjJa7waX8_2SaxFco1?!2HYI!-L z_Qi>%c>1!q{ab=x75wh;#pA8n|7d&&+ZxU7(z3G7EGCcfJJ0-sw{2C64;cQqWRJ1;L)g5!jK$%7^l!Gg+TeZam~ed700W zvwcc@p$Pt}-Z34aDGHKRkWm#MS222Sd<($j%6z&0d}C zyxLfl35Weu2W8{bQ8{t7*XUwVeZf%k`uy8kaR(Sz&Sp~>1t-Qq@3h%irNFAx>*heX zJIR|(SCoeFFTbvhmH81@Vfx|gM$Px z`5VRuwk?i&JGqE9A;e@Jg;f}}IgL;Qj4DerlTUlEMxYI(6X07?xDSgDD1`e(yaM4Y z#_X;XzdQMMZ{}2Y=avWEWAYVfJCa|C^v_52FI03dNjeZ53N1ufuE#f9VZFP0VLe5; zF)MSU>^Ge=-x8l53;vS+S!ecNWzGJY@%2Z>#>&P=jcs`!>KJ3^8i0Ztc?~q6v7wPm z6R?rt8z#*R%_MCQ;svnNX0{~@XCa(`uqm@8dxVmFu zKDLvchfx({QHcejp&C?~sKG{rjdz;z{Jc(W{T@dPXUVI zE6h8?mxx}l5^5zn){l~P4*l>^cuPphWyvAecqvJ~U)5!`xe_m(6Hg)dZ}czr_`fRa zCydK)G9G;%Og33e!lvaA12MZ|F=CJ^L$%CmlWI_Xcam4~CYY*V)B&mxR0UHAMhqwz zGE8pZW-5XVWaQbUBtkEdB$CUMAh|4IB)PJCD40rJR2JF%aOR$35zk&0FTW`GTl$wb zLcVJ2KQK;x7_Qtf-ZZzkH?~P8Y}Ui1a1xV%mb+DpjzHjF96HC|jOgwuU4t`VckABbF zaC{X(0=R6{{{@^5#-lGlHMV$2n3`;}w&2BMwh#)0fT~~wGex8jAP)Z~8iZ&v3vR)} z+Q)P(nAR1m3*24nX-gGhE_p$rWW2be1}nkwql_PJ7Nt=yp1drsN74VUz_Z7?^UYTo zB!JrBgHZp6aP7MB<|CsYn;p2#Ot#g8ATMD6ONJ5Z0kj|#%!0+>W_Spy%;GSa8!+5E z8Nn@>io3vukp?$+|xA&jf50WbIh%5%u z9$@TtGTRO$SXSVe4y3_)88%-!W)0+Q@N{tu;kcf9&Yqhwk>U8q_m2xpE!|>g<{L-6 zIF%H*tXfd)y@RC6$t>d=dw6E*zj|XP*4!%dvpnYeoW@Bt`)=p|;xu}Zp(3#7sD@Kh z%H@rx{zRT_)#<7JdF%b2IoGTcGW%Y$el)*+Sw_cTV{co1m;Il~7Y`hp(!h1}YmBZJ z=lKn$vvhA1OmS(k5o3QE?&Ve5-prZ(?GEb%1=ndY_uIA|pC)U5<@a6}^%X8O-xS>N=;0uEIgTN Q160J|>FVdQ&MBb@0JZg$OaK4? diff --git a/android/res/drawable-ldpi/arrow_up_float.png b/android/res/drawable-ldpi/arrow_up_float.png deleted file mode 100644 index 8b60f121600dd043c7e0ae5c021153edae15cb94..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 422 zcmeAS@N?(olHy`uVBq!ia0vp^JV4CJ!2%@LY-GI;q?nSt-CY>|xA&jf50WbIh%5%u z9$@TtGTRO$SXSVe4y3_)88%-!W)0-5^K@|x;kcf9!jSJ^07JvW{p&M>=3NUDnpkGA zvms%zUgFe}S8CJFUHittmuPg;qE%XANvF$g_xX)S9{k^SpW(ofWv#p-cQh*+IXPxk z{J4EIr=lhx_@hg+gOGsQ%pfmSNkv8>MxptYbEZwb7BxL|j?r;g1{&~YgF1>Y5_Cu4cK8X1nZe8v(6hmj=b`bkDwIXg4xph9t*s42dCeP%pR*A zPLbXmYZ7$d&J#4^#|GpFX`&3STi@z|CrA9#M?f$`*kRQXp4~JW4IOnz9hR3Sf{A6v z#5r)n;--O~w9$jb!iA4R=)iOa#~m5iiBZ|PxemQ}DsOdncq+G%HsOBWC6yDuxAS18 zSOJo|eOES~lZ>Z8!jlXJwWn^TmYlZV`k2Qvy?)J3)bQLr2xcn?=$TUd=zy-n6y<%0 zt$%7e_c@=ok7AHJS!5^O_Q}&Hull#h8b$&8Ixu+F4dRD{pW0fMk?tE?0=Mp2RQY`*jPQ^Q<_u8d%9BErzZ5HO|Kyne+ z?YnWms^gZ8y+xrDNT6DX$%H@ zCgXDQ)~}f=I;GL~LufKaoUL(-zZxEBe)jtM zaORpszV67k^ls~%RZfL*y}b|FH*uMHbUIrV!gnj(IxVn1WEXQu&-Pg+RU=~^-wzzu zZTdSd(TMoRZ^o(*oa*_|*gEl2fm6*Mi9#DgK0MX}^2t#xsC==wIsaQjGDY_&efG?s z09o@!(#v_Tkcst9fR3`F{TX6T{5VBQY*^G+wx%^?j7C?zrNVven0=U*ADFCaqE@JL zzcTuJyyV*u`vPdI-!Q2)KAi2@?fj!uw08Jf-~E)~_*LX~s-WX`42MteO*_8>@ItxN z26ZFvhElGy%oZG=cgGZqXnyx2TFZ(eLbQPHLs2>xqtQ#;ARA|=8G4$c&(RIZnazvM zD$O^=A|cC}x^RBv#hmA6fvbXLRxJ#3!^-^ri}uS$X|?w-*kkR8tXH!6GvvCE_EzF_ zyc_FK$Yot4jhQti_GwD@eB|sFevmt?zJ&;vKbTt8aPm707hW74W`8Wa6vHDNX9P<$ z^-Pf3$|lOGCbXSz%pxA9XJjworDeS1V#5!o1wp=wBQ&bwA?jfv3`Z|_=$fod)$b`q z^*P?D^hd^pWfMbt)_0g5*pgAl&+_Q7SM^}%vDW-_d{*W%k4qEJCg7V_c@>{Mp@3hg z3ya)a=~|Of7DW}|A6OUIUA{WND8}Lu<3#t*Y^&T=JhlXc#llpZEWPAzP)D&8xWbgMVO16pKUf z3yJ0cpdr>JihWF`HvCJ4g!!=|0psXWxR%VQtQeOt|0u36hXq(LWpW24)R)b2X8AIC T5n|Rp*&~2LwzsSz`6T=U5hc46 diff --git a/android/res/drawable-ldpi/ic_menu_archive.png b/android/res/drawable-ldpi/ic_menu_archive.png deleted file mode 100644 index 719ecd8582b8c20ee1974a2b3d1047966e85607e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1140 zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k0wldT1B8JTQ)s;gd%REeX z#SE*BGh6=nq&>U$d)ExlU#e=8^Iolbf43$^?|kjKo$dU3&+EI_*4dnmmU+&tWn$Svd-IRCEscju%{4E((96rW4cr#ojn?RHvR;NEj^uZhIASqjfI3IzO9N|kg! zeZTdwBhHRh?qT!U-ftgu&1Zzjb~fYEgN6?YCSZ=F?YH5@%dDmr@mx2yM(-*uSQ9D?^glcirBfZwhU%tqb$q zyy*IhC1&gUSA4LMU&pRGL$Xuo%!B|I7sK%0>Bpw(AJ9Mkygf{9@)8-jFYGTKS@Oj* zaB@_nFizH4{KeU5wZz*A+&}$1ytHe3_dWgTsJ;Dr-^O}T5dk^>1I?-bUa9Z<{d0cy zW3_3sZ)`O&DgNGN82k5=ukFdWxIGCX932hElMBm!90~bu{*))z$#Kb&PhpGyU;FO& zuCxEgoQVwm&RixdYvcBsnW(T{TEL5f!}QCs)QglVFu#`{QO(tb1h6q!gbGe7Nljqe}7B zMz6UJ*UX|`PgGVC_;A%&QHn3&)}&+(^ZG@0NAzmvzYlzUmdSD6k2mYq-9OEE@ghg4 zTtWKT%#7sC(FVtB-X8xr_pd8c^i{Q1`uC~lF ztz{oKzAKEq_9jG3;q;^Vn}X#I8O$$CpUro`+vZ4MS;5^r`-FM94o80VO1|m4b6M(u z_L;;r7m^(l-rAoDoB4oC?5*0gE8g<$pA;&laen*6*BrQ|*Ux+9N*6&>xww3m4|;;U zRhcDnt_(>DJxswecfP%O8q@TLdtGIl+qpF*fx!HwTH+c}l9E`GYL#4+3Zxi}3=9o) z4Gnb-j6w_ztqe@8j7@b7%&iOzCW^1RjiMnpKP5A*61Rp2UP7Q8%n!05EibP0l+XkKu$0&( diff --git a/android/res/drawable-ldpi/ic_menu_info_details.png b/android/res/drawable-ldpi/ic_menu_info_details.png deleted file mode 100644 index 55c57d5c544b3119da1839e8028129cd45a0230e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1499 zcmZ{kdpr{g6vroA=C$(3V|}i|5=EQ0dDJj_H1ZbFY}t&)m{%mZd3?P4s97;aNRlaW z^N1uvp1UMmk1#2ZD22S@PJi9|$Nl4+@8_J~`F+m$>!di?qogHNBme+_GzM+sB%sEA zh>HmFIiQ1_00)TYP&NQSd4{^4paKS?JwgRU{|ejAE0+7sh+u@DfWN$et770=0Dwp( z#s=Yn?wDYDP~BV)#xO{`-CDIzk?;QcZ5#^;X4t7S``hw)j$CY}1J9*lo~*rggaAP*%0w$~5q|5-xzYFI4W^P0XwTilE_n~c^eO3PO)Pf@Lo$wv!dCsNSQG-g;PH)%ny$F1 zm*3;v9J@Vb%OP25hT5iH;M1%6#ZnsH(;c7tI$v1fS!tXJr}5U|MmT&M{ zC?j^pJMjv(RB=oRBNQ(+0-PUz-p`JSZVVol|iAsSkf< z<{9y<*hRY{?JjR=)ZO56OqZEd1Gox5}yrGqnEx4$!c|_UyDhen(PmQmIM5LrP4sT%@EVu)OuET+6%ODAAZ4 z%|qSq5R%@}1YUb{;3@y;J`v8;wf7*`$>_6)%Bcq-!Ka|(O8<~|^{BHgV z>{n_8yyMAy$gephej-)2=LEjVXFa33+a27J#1Tn9aXqyBaCXY(BP17BBz23>y4{ZR zjT@qYmP9*Cl5Ok~2s9hzJITCdPtC;jqi3WW*k|pt&sw3w2QX+zD>JWw9UuS0nUcR* z*xSRmHb%~Tj0*@#kwqKWXEuHW z=BBkITc6}`TWtA~3tCZ}s@hKXi@k65RA<-Q&r?5*KJ}_t?uF#nLOc{%CSb;T&#uz5 z9PP$O;<*|80lV{qK-O!cE)-b(ixZ{*S9_*Im11Ifnq{JSJA1v-*}~yoWfzxRs)C$} zz}Hh_P-*fP#BOC)tUp8ye-%S11=kkfu8&*~SuaN%(3Mxn=w&do4{sdI!(=_7+>82B zk;xm6T`auoUHr%Lv|H|GD}0>4dkZ{zW17x7D6(=j&qV7suAAX{@=}>8tlRL)F;Ktd zz)p42-Zh+`Bv4L+xw(LSSuoi&H<+#=?C4Gi{X6q9tA_T_*^DeYNQZtoV!CJ&P?T`p z#o^Rs-O{w2RKopv+G`?n%QRrf-n7k&*WBe+SfB`d-W9#~RCSkO{&{$tL#((DE@n&K zHj7hO?QcJ(vKa@Wd^i}mT16bWR=Lv+;lncZU+FM}Ca7eonX(s8(YyF>px6~Xn%Egt0DvA82GxPVbf9`JFc=(a0M|Fvff~c1&@9FBvHutXX}oL_{76nDf^SqvC&^qe1i&EeZ7QvNZvF!qke*Ed diff --git a/android/res/drawable-ldpi/ic_menu_preferences.png b/android/res/drawable-ldpi/ic_menu_preferences.png deleted file mode 100644 index efc2f3e4597e6f8aab0ac8e4156e83e999a55d01..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1601 zcmZ{kYdjNr7{`|qRvV2-R;E-g(I(=|Wz=dL*}){!ZORD4u!Y>pNfXmlLyV}9$>pG$ zTckKks$qmN`A|)AH5$v|IbUM0N0!^H&xSsieaK02DQF zXa{#Je=?m&$vL@|A1@gSX`E&HQCR$&xp+sKFmm8lRNw@dBWUTRB*R@pf78oUNSRsta21E zP2E``UHuwA)jzyCn|IhFE)E6WQ#eS|9b%rhdFCINWYN3GZ$<3VFay{H=QV(^$ktlhcC034PYt z&7#B(KKrqM08IASt;lxxo!j=P_@JdMsZeUwYSF_;>_#z0^`-@hKswlTT-=_&EiwcD zA-om+)%_-RS1M%IrbcojuqaT8neULB_Qtd{ZVdTjQgZxYJ3kXym%d#kH{k>ddZ=97 z&l}1jz9Gkn!#FvS$2SuA*L8Fs^GJB3wt2>*l`L7$BVbi)o7@M;Ud&n)$`1DD-(#f%(em`hy4VmY2ehcsEaqebcVXqv& zcCbmqC(>6;9GtcP6Gp122@m935`;LT&X(**uckv}+#-JDx2V;48-qs7)+n`an3bUZUM>Z>7K+th28FTo zA=-GY!4!2r)q6jJo>%!g$r=ZrfrHYq%HO}UIOlkz16ZHgk+dA8*aRriP=w1viJ&k& zh0d0Dt{6~TTBm0NDL}h@@I_}!Jd)`mx%v5~jRnxO%$qQeT?lh(;Upz<2@VK}qI+4Z zq>;26bh6t&J0>)0sfpQvC%hxG=oA6ViCwIiKD-$r$*ER5OeGq|#KjeiIC>SL8@lFn z?c25xg%S87U25h)&kZMZ>s#ewSY@E~*}j2o&N21(Mxk`Or*kDc$hYtAt+aj>`rMxs zcaEN4c`P^U&cz~f>B2r+lw&48cCVF@Rd7@H9HX9Uj>sY0`vBTZ%c(8t+?m9wo#o}d z06U)eFb)PoGDsd)X%Po8`|?Ij1Abn6ek$5<-E^~ShGmWER*tt0Yrd0Qx7BoV9UJPb zkh@Cl& z3_C*B&avv+248;)jU0wNPoaka;HC%y%`Zl-!2eQ|kn`klfH}Qbd6(R1uNgv!FD=45 jj0|w_kxLjZ$lH(XM)vlJ3T-3X$cF&9qj+@rVN$|Bz|ZR- diff --git a/android/res/drawable-ldpi/ic_menu_save.png b/android/res/drawable-ldpi/ic_menu_save.png deleted file mode 100644 index ac053b41d9672917f846216d94d076664a58fb5d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1279 zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k0wldT1B8JTQHtr#pmYkG@g0kq>8T; zXYLdgy{w#&EgD-EObOuH`fAZ7t)Pub4u%4Ee_TKI$p4S?6`h!lCcRZ#oi4hDZB=^2 zA1Y#~bxSOm*JW`g=Sh>9XDpu=7p5=!TzoW-b^mV50=s+fYwy3ejrpBA{b?by z{=aVvSf=k#HI&`lzmlaX(zY(4=u1Vx*_$_ux6l1)AlP#|tZZ}V?^m{2O6uBcrm4(Y z`bem2jTgtwb=5+ONui%x=H+OwS+w=5yPYWYTt~ReqRN;_29Uq)u zt9Wq2+trUtCWSNSM(6v4R3$H+TCB3;$>%$}UN?qX$DCa}ZK8r{`H#8klXtNwe{^uw z;cGo)?fF*zqODFiyO{sv-(h^V4`rJYvX`06SQ}7LeD{<0Y;&nlTOon3J9o$B1xz$( z?=-(H=*y%pyC*=R_^aICGpE(s^*g(MB}+`*zU;%NeYZZ}+4t^lYgGTY#ge`qFUrUgd?gYfC#WzcCGO`oytI z$#CAp2KD$oP5D97Z%>;w(=s7;gW~>(GYbTMvb$XrnO>6d?0wvgd(&U6zAee16>l;( z(?)G&wo)YHtflf9mV!R7e{Ks=^p@dq2)2;_^KkRGBMb)BbxvDN940zmZ{5}?D&;TN z`E&L`m8K1?+-r3?4y7nBe*DM5!B|tZv^!U2Nr292rDzcetbtCqM%l%yncptHiD0ftL`dFyRN;kd~QKl3HYylv7&7V4!Ch zT#{Y`l;T5@%E?bkEoLw&UBRIQl#v9<1m~xflqVLYGB~CHB^5k#6Vp?JQWH}u3s0un Q02MKKy85}Sb4q9e0NI2k9smFU diff --git a/android/res/drawable-ldpi/or_launcher.png b/android/res/drawable-ldpi/or_launcher.png deleted file mode 100644 index 5f7a0b2ae0b38eab2281c43c9154d8eeac7c2fde..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3114 zcmV+_4At|AP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01|Wn01|Wo-ew_CX>@2HM@dakWG-a~000Yt zNkldCU;n=s zX_3+sX{(|S?7O|#Kc2PrdY(W0H}vlx{&2J_uPj*wEF)7N<~iO z?d^XGV{wbyt(x)t9CID?#FN4{~nwCJvyHg77O)lYj#Y3WE>AwG;f{N zdh=pY?i+Ud)xKVb>y|A=PlHjtTDR$i?HHf&K0ZHd(mCIzaqHtG_*l1f;}30Zq&pt{ zZTZ6EA5j4JhKKD(pEP&<*!4!*T)gAW>nlHU)9?dT+q^Yiy~=cFhso})d2#86&Z4t+ z{~~Ziiq&Ox``pbpY;gGC3i~&EtPQ(vwP%M_VQ(sne4jPpwisHjP1;#gha9|@;9F^% zMplOdorEs4i>Ke%sZ$S}FrmR2S5!ZH`@Wwp40qACq^8l}z40M%ZvWPS?WT*Xlwn!2 zwJyAJ)pBlP_?fpA#3+q@xAq5ee649uO~=hAeH*@>LNqBRO}^DT?!Hqm zoqc6*sP*6dis>b>(YmT1n!#}Q!b9a?>i}&_YFiW9mUHC_7sCo(dsqz9x<|Bz7tR-S zE9Kl3PtJ+!)-v8_UOp?V_A&=nUAfWiJT&aN>lTydPg6`^mXxxJh{mY*KKw}96Y7{T zHe^#+==|DKAGy664NmgdW5~)nv26)$%NO-l&h8#2rV{I*u*yztShTQcGCS9V%0+f2 z9upHK3(7p^-1$sB%q$yun`nApjQ)>ImVgkAkT*<_J)uf9R#Zz>mJas(?VZm&b*z5j zD~#WMFBg*Vxz}o*Iq@E1r;h=0h6tprs1-CT#u_@kOuz4$?iyAHiPjsiLc5qyrv~rk z&fw!?J@lgvZLvg+Zf~cuQ)i8KKnBBR{N}^ zI0s-51|2Yh^%6D--dao`hbx({=pRDR@N3Z70cFt^P;q;q-mC)ahRRac` zF%$(@r)V;O(s9DAo1RH4eB(l&$~e~hbNa5Ku!dgYC_4^oDx}HGlYg6JJ&w^!M$N3) zJ9}bjk#28s_2wLB!z(#+RfNkcN4T(cA7Tnn!KuYsr6|BT5MWRWw`~UcMW4$}q+VFY z(cxQVa}bEF<>Jl~Tip>IDH(Phn!NGBzawS7h@pIg?ThY_^(&{=wg&ImIj8KV%yx>5 z?|K)qu|*brecw==HAq&rhAp=rY&kH1K_}q~%aMa6w`{@ZUdWu??lPaRu-Th&c-WG> zvfCKemmRjS^e9fv8{ZYx;=7=}@x&9=*`3RetTf}_Q&S%v)eGi>A!+MI>XUckoT6U-P*$>G*t3l5l299m0UxSDwO8-_Yn9N1W9*#^=qajg-W)-Q`v8BzOPP#WX$ zLed?Ji|5nyn`er7S+RQk5w1UcJ%_56VQ`bmLjDBKn;%^Wx)=_ay3Il6QWG8=iT1 z`QC7!J-x}=u^W-@66b@X(-FE=q^T7(!elO7n$~1V)M3EBL7%LGHG(0(e!0d7nkb#H zTxMP!1v(~ROyR`-#YeS5A*U-i93hw z^Sspco+NNfyQ&Bm?QrF;pMnzDKq!@`lFrP=V4Xg|z z2Ua})_^RdL5)&)ZifG>R@2iUK^{Pxmrk3-gwdQM!V@sDzB)ZHXH|+225c_at(xc7F z%jY}fl-U^6?7GBCKQpKt-LjxxK*t%ZCX6PUMN8eZBpM3Wa&9Nl1Z7f~Z&sqMs_q># zMP8IPN~hT^7JmAP?q%tn8V z(M+L=RbfyTEIAlooskv`7CG|L`IhI-CfZ~ONuEtnYas63r*cHI*vs?o;)N@lpI_M7 zp{i31a)QDNi(GJJW@y?>j7m@ig?Vil0kcKPjR$J1Y0;QKgdRdSWcv^(`h8Z@-2k=aQ>+hf9+R(e(NiDz68! zN=7shik9qa>KKVRf<)$$SxQ1Bi9$0zDn2Tr7Ds$4#(dTqYE{|Wsd+T#PhTuv-X0g7 zPP(!))q~H>lRdE;%Z(-vNb1N^gSDs{&~HNtkdPQymB>6t#y&uf#4H3A%AC0{ftRA^7uBBQ)Z^ZxrycS*w7{eN_6V~7HOXoHB*CxokC^L!Qs-$ z_vhQ>3kyqnplj;e=AnH0V!eJb$G9drUyq7K5=cb9{p5hAzxAMfoH^%+L#IMv$z(+7%6&lV=#HgxlMAL+by_qw}MN{;m+*ea!5 zYW8UMXlgOpv(;}n*bk5c$+t{v;li{_9STG(KH1A;|CcV${#wbe7|bLq?NrK?U%V*z z=ihklWB1>9rG2N42FK2o=o6~?>B8oV9h=gUoyCsMMloySv#BJ-j!MAD>wrxg*q&w1 zjteeMyUasLNOq(-`~#`}3oG?MgPsL56||jc8N-=N!tUeBw@T4}t;4@*iklAEp^3!+ z-zjbA$845;cKcNIdR307DNbO^A2P;l7S0Zxp%9~4MaLp?!K(kNQ~zZ}&Zz1ouoKDJ zX7H0-rEun=aOH9R&*uBRX!uLU+IpOOcmA$_7A4VyOq1V%GLjV8(07*qoM6N<$ Ef^%;ny#N3J diff --git a/android/res/drawable-mdpi/arrow_down_float.png b/android/res/drawable-mdpi/arrow_down_float.png deleted file mode 100644 index dd825234ca530c7ec21f26211ca4e0ba9e950045..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3141 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 M07*qoM6N<$g28)?i~s-t diff --git a/android/res/drawable-mdpi/ic_menu_add.png b/android/res/drawable-mdpi/ic_menu_add.png deleted file mode 100644 index 361c7c460ef8cd5225a54f6ccb636cad9b4e3aea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1339 zcmV-B1;qM^P)kdg00002VoOIv0RM-N z%)bBt010qNS#tmY07w7;07w8v$!k6U000Sga6xAP001BW001BWhx(kI000C-Nkl_>9LGPubI-lIciVMtyL-^9Zs>Az<+6s4G&5yrIu$7;B*G#JLqv;`SdgK< zFhZjj(t1(RA|w>itT1D!3rwu#wx*5E)o4%ds_d!VyL-<$zh2zC+JlC@sUIB9f&ck_ z_@DFTd=C8IBmcNEx~hre-lh;FSpZ%I;B^2}1etelJ21qpBj6>QEd0PAA$o}<5ff+9 zKFrBLN9`<1bM7z8E%8k^q04Fr*Y@0KvVU|!$i#<{32`kmYnR@)a?kXwrVo`NgcL-> zd}bZ&YN;u^SZg6;5i&krklb4F!lQ?iyn0MO@4s@pcNnsh7i4Tndr~5@d*p-j1*cnw z$0HIm1=wb?bzhZMU96hFpADXT@c@X&lh20v`!7~$)xIjWZZqR|$Hx^vO{HJpO8M^c z1FnyG;%fJ&T&B;M}q<`UBl|Ees}%yqO${fEy-o~+0CbN7U#U=KAqLw%z!0Myt6o91;CQZKumXb>k0ZW z);R#nqswC05O6T)(-S+pV_F$t39K9~J^uQ>Rnkj}H@S{jEf?s*6lw&(7F!VLGXzY! zS}q*1Hn~cQN&iOU1sH#I5nL63;~^TsZTp?M3aEh#959`r7Xr)A%{wr3p}^*T5e%I(4}3 z6_P3{7iGpQ5!9NcQGKV>T}mqjAwlLu80VR zdMso|s-pO`(eqyVFNkg70!gIefJT7uZGF%%{Xb~wPY+*(lX-gn%iC{~( z?q$r>EU9-0CsJ`hL{LKY(F*U}>;-<#4xCd`IAHDC9Gx9euHHQ9cE=D^>#)B#dnTVm z2_;gA78K~H8Gtpp%mKCCu?lOKA_{^)rbW!_0CU#lLd^gjqhICUfS#JRCf)Aymf^#( zjgEM~ilSg)7-0vWw`{wwNo(5Z84o}N<J~ zjgI$$h$?}MXHOPB;=B<(&|sWPX&bai@-sM+VuoisD=JI&d%iO^HsAh;nPVrppt)sM$70M)~xwGtzFD`h~n?t`eXs1F@ zN+eBh@K&Viig_{`y1UX6h(dSs!)Z&_=dDY9z{nBk)kf#bp)cC|zb~w7j!o3rWUa@& z>miSPvORu?4$;f6v=g1|5 z8=o)$001R)MObuXVRU6WV{&C-bY%cCFflPLFflDMI8-t+Iy5&rH8U+RI65#eq)u|l z0000bbVXQnWMOn=I&E)cX=Zrk4UOiAAEE)4(M`_JqL@;D1TB8!2v z2N=7Z%(epwmK8Xr18D^?ZvQoBE>N4hr;B5V$MLIE_GXJD3bfC!ydQghcejubwz?POxFG<92V8lx;2y~S7h;uaE&CMBlDS2tg>s(wAQW!mn-lgB3- zyl9(HYqdr1fOA0CUHAO*d@iTRXPRNB?;U+BuQo&8Y|TG`Tvi4TyF1cbSf!W`BpyC} z`xjsF`V|wWU4MDtNI)k`=d3=5^|l2Q*4ftW^ssx_x+BAzeWOI%il2-0Sj(3_4tgK6 zAz0{Rm$`N9&cjMRdajo&?$STnM-MT~ib%Ev2#V%AM$P)BdU? z55vaijeYlyOI;2~SiFamD{X(jSCm!QM*n?=Y^!=5ol+8BdgL+d`8K5PTxxPKhDqT- zb>H(7ADFd0PEK_%*k|(mKtS(0(e9>OAq|0V4lpGPTw>u+jNUxOU2vIiX4gu$m!gTr zkt};IoD9s0T{Md!#+Lf@}!RPb(=;EJ|f?Ovz75Rq)JB bOiv9;O-!jQJeg_(RK(!v>gTe~DWM4f2U}0P diff --git a/android/res/drawable-mdpi/ic_menu_info_details.png b/android/res/drawable-mdpi/ic_menu_info_details.png deleted file mode 100644 index 18b15b5addaa6cabb3c762d2464bdc26c4bf8ffd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1237 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UOiAAEE)4(M`_JqL@;D1TB8!2v z2N=7Z%(epwmK8Xr18D^?ZvQoBE&~JeT~8Os5RcKO*~zCK~&O-7Ao~AbGr#YwNN@>wa^8idq+xeyUAxLKAoKuMdaPg4%UB_!b2A z2??HJ{Q0av;M?w97ST3b#-$rdIc~qEdhUx#{R6h7)tgNm6`NO_c$fRz?`i(U z8FPI985vqIx9*$n^n0&h?)1aXYoCAJl%d$%%^CMh-BGhXw|;ZJm;J1~7nANkl{aP# z^9X-Ajajv{F;&R7?*0MQB{BNCryK(2-T!&+=+pX)FMj#OrEj#=uS>^svzoh2Vt=cz zoW1C*cH9Kp!@Bc7KWEm>`L4PuB{j76bIi1Nk}p;-x1K)x+nIyk@89|O=zQXGc{rz&hk^3rj;tcC+Kly`KqOj**EsK1w83JwrB6W;%f=7*Q%Hu z7EZ3u|6yS~ueP+|cGA+Qtfd?>lbM&g|H(BelkJi{n%!`+Z}!&Yt;w?HGg;PKo>~}@ z94_tt$EB;lhwEiwy8B7J*wCz6BiHD?g5JCd?SCVg692F0^?ar2&AYaDwmt7OvGTOj z6<+MwjzL*tiSmku*= z*a$ZqtQ6AIdVBlgxxgE8Nvba*j-Ozi$_VpI$C96`T zj|&}P+pu=Zsyxm`4&P7CGh4|m7QTURIp?!S%BGi1FMkw#HtRrQY@uuH24BB#7v3t# zr999$^yW<~f49D#eYi;N>g^}D7%%^t{#l`7`cBKl&$BWwS&Z8H~w|8`F zHwFFs)u{G<$v*R|cM?l4r7t_cwdvLrx6^jqZ7Q?=tZVc>p|^L_jR3BW#Y(%kzqg(n zzwGU&(oLyKc8f)Rm9=T@oxRnWkN^L-wQ*v)3j3xgH?|5+DZLkdKd%1Fe#Ntw*1hgL zB5r$9{wMdx7d5{UbhEZEn78I9Z_u{Pt4%BWO220w7oPFzZ{pd2*(y>>{Q47~tn;ZT zoOj_`u*{}276(iO7;@C+|4FKR@n&QA?aTfD8LA#GJkPNHbY%}>cptHiD0s_>~&paw~h u4Z-k4UOiAAEE)4(M`_JqL@;D1TB8!2v z2N=7Z%(epwmK8Xr18D^?ZvQoBE&~H|ou`Xqh{y4#A+b4=LnZ3&eXfmvd8^knnmajp zwXv%2Nuv!d=N4S^G~w2`$g{&h$54r-*Ui`9qDv3cL<{4K6^-{K_8PR!R#iK^Q({G) z!L*$(I9wux6IVwr+;R5S)vb5G&z(1&d$+v8g_m5ZK1x5#bzk0^`0urxR$=whB zJz=ekXUqn_WlG66Kc_ZlMs8td7HiyS_vg#>cTp#OSPTSxCD*Rpx41*}?Exi&Q?Iwx zJzQt%yQ#C|%_LQ(tesQm94ZOqHk-jzX|gXOTwgaaxufsNc6BeKNXA1Vla8`@FjZ!3 zS$4C*mBnSHec!<~Mai2!JUPd-!QGhEm(ORn|OR!_DA53IQaBy*Ck zHMh%i%C6iIUzqqvvW-)t?NF?hLc`6M2D4WkersyYvN=gBhP`A}+LNh_krBFu(V0y7 zLJ{io?Y9_5-CnfUtT_MA6r~^qhTe$xuBrPc9E*8*wAz8Gi}7J-|GTW5@@o%_D-&!A zg{Dh?oAYg_4yT&)p6Qk4cQkz+{+Onf9-OmX;Y6Fv^pLc}z6<%jt63dh8*I-v#dX55 zS)M6Vxo0V~{;B&NXMf^g+s3u~(mD3OEVkF%d1W5=&cp4m=Lr_xGyQy(^*>_5St74T0_kJ8tFr&%XGiqQ|YE)tI62z%KW^o02v$uiTecDSymlii)+dg!8ETLU-W43EUJizgCZoUfJ3ntc80yOi&i=_zSVd+u!7 z{jeih)o$whBkR70@~ZkYi?D`DwRkhE(s1PN4!Qg)e{w*4aJha}3-@h#4%xLgJOsC< z7X8S%nYpA+U8(z^^XF;8HsbnL3>iEOXREfp&nkBPapRSlVVCU7bBT{d9%XU_&G1(~ zrmMhEcHTRk*-rQte^$WW9AOKK-w!?BRsTQw;{NSo=}bctffTlSmZ;nl)h`_%@2E1m zcK7Y8Q!&1d7w?{ASYVmBQ2AeD+0uP=H_t!1+1X#c*3WX$r>;+~Ct116Odijfw!_~< zVKtj!+w53|Jyql51QubpI~&@49t?MC9V-ADTyViR>?)F zK#IZ0z|c_Fz);u7BE-nZ%Ea8t)L7TR!pgv4iC@u46b-rgDVb@NxHViAK2-|TAPKS| sI6tkVJh3R1!7(L2DOJHUH!(dmC^a#qvhZZ84Nwt-r>mdKI;Vst0F6rPu>b%7 diff --git a/android/res/drawable-mdpi/ic_menu_save.png b/android/res/drawable-mdpi/ic_menu_save.png deleted file mode 100644 index 5f6686448d831da67e8996c6f61eddd1ed805b8e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 981 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UOiAAEE)4(M`_JqL@;D1TB8!2v z2N=7Z%(epwmK8Xr18D^?ZvQoBE>PQDPZ!4!kK;$Dp3e>m7ddYKeBW=i$%ck%xBeI` zxh0aL%GuOCAxS*zZbo#5`O?`ri)KGM*1G%AvHFG4tzHTboH}+0#_X6VG{q}MM9?)l z!;L#Pr{t1(@%`%WJ7%1;c<*ae82I5pbtZ0Dqr4c`g}F_{!QDa7X|#-^qxVpqxaPM=K0I^fAxNLCZclQa&29X%LYPUMAIi3 znhU)zs?gA`ZD01@|F79jo1ZD4b|3yy6Z5v;|Ju4<-m^x1@rK=z470L$noLeFX|1?W z`=Bjmy|(3trYk9GkvR(cCMHWZa7@ykwWxH#iYwizo3L6;ziivWbc?%tQN#J1 ztAgR*J|BI)U^dgeTO2+L9ts_q8^sxf>%R9{J7$YV^=co;F*v{aRZxtFP}z%O_eZbK zvMH#2mCl}RzmMJTt!?FG$FLv2Sh=)VukSs+VIq^#r7g3{ALvgx=WBB2*MfSgY&Y%v$<>Ee5`+#61$mM^}QUF*lzG|}r*XyLksJl=pO^LE#jzBs?X z$jG5BTi;IRPu;rJ!VDT(%K!V!j;#=t-BWioD?IKVo59M>!Q1)19W7iIqiKD1>#Kh6 z#7XkcZ5&)Dy_h~dHgi^BmDjVtBfHe)a~X6C{y)0=|4)etOyO_AZGT(?#q2?Qe2z zSa^Na(}$n#XD3P@{Nm2z@@%aUx4=P-2kLJ>1~aSOec~+=c~!HUeev7FOZrN^Up>uv znZrNZwRXndaOKz6Qe{iLpJ<=neE4?`&x%c{9S$etJyRv`>rR~XvzOmKn;>08-nxGO3D+9QW+dm@{>{( eJaZG%Q-e|yQz{EjrrH1%F?hQAxvXPx#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iyV= z0~REyR@$8a0013nR9JLFZ*6U5Zgc_CX>@2HM@dakWG-a~000U6 zNkl^(X_^~*=PWlx>003-W zzYR_iBS%qMSMx>&#r%Ajszem`?{2iqget`%S$wjg(}b7N4U94B>)ZRB*6M0&E#j!U zfg1FH^LBEQ4s8d}3xL?iK^}}Tj0}m>8ri_wIF4tA5Xcw;55AMb?vYc~RYnj#>#u(A zsMXrQ>we;3x_f1Nd;1mMd$QJ|0EJQt*4pOFIme3ciF3}RlvOEZMF?^Hpi5u?QLWY% zh6j>Q=XPjAM@Pq0=NxIRnK1@h>n3%&lzJZ z4D6|Y!vwK4j^n9BM9w)TrGyXyN~!k&mkTNHhY&zSu+}oG{jU};>Dql88 z`fzfK59ZMdtJa)zFvc)rOcTx+gHpGx_Y1i&Ypo9hDj+=HjYtJK&kOo$tb0~wYFld-Q~R>KIYI{Hf+b7OV5W9G&V`n zg(3J`iQtVfk=B~EZhMhz%?P*Zx`3u)fk8?M=lnXY%}xMd#}XC*vJp8+nrv;gTAk&b zBV$ZdM68*7tqE5`N-5tLaVaG!rL+(t&NIHIT5X&Eo8LZ2M-3f9Koq@~%U;lV4Ke(e z5W;7@_ud#2JLgC#)ztCm3ej3Ylv2&bIp;_S!Lls7Z_%Pf_X0rgrX4Wa9(|{oRy&7`$I;zl!#IaLI{?oXkCX+qAToEMC%;w#!qjtwSZQ?C(wjl|&4!jiP9__dXP@mK70e zMz@qitH&r8Qs@^-DR9nNmStUeDu49&6U+F^FTLJ$gGUSDJt+mgx%x77Ce|LA+y}cWEVCiFv4{O&y6ne&t8H|XaRk($# zkzWHe(OTF1^H#9Y9j>elf6W?<68TyJ9V_x$%l4 zhCUz>ckbTtvk4O>oC!b|kyJ`4$T2lt-(FFvdU#(exi#mJRS+F6dd(-MeYs zR$M&y3&(8OH~`uh!x&@CdmkBNB5Q4FFHbebc<0=hQW`D5)M6{6JkQ^72D2CUbbV+` zKH}=JdHpt&*~}P|#pzBcbW9-xX02_r){bdSv|_p-Aq10B8qT@R^L#~?h>ITST*zPR zee;+D0{~mQdJ8U}KL-FX(6{f$T;=x{7O`QBNv*Y?GRDL$t+@2d=NwX~ zKT4r*>si_rj^{}g0|4HjNZ7_h#>(3PusqNArD>WfrN$|xPSaY)t(~sLKPaVCCWM%r zW!YVwot=vSKnjI1W804#bhK|*7UgQ_4uZQQj$?Ap?G7QNQ52m*M5hr^TudVR;6&p^_vmMC`@!uO+s#+Nmrd)oV(hrF_}{Mow)O4Z!}|8_ zslM~>+cag$6k>?k)H6?~?c2B8uYcv+_HS$c+&=rlFGh3c&ZQYMW*7hwW6ToKm}2KF z01u!Y9Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iyV; z0tyB(ie#7o00TrxL_t(&-tC&pYZFlvhrgSqCbnoaC{=4}wbdpd1YC%;o7ROD1Yawq zb|Xch;zG17;$PsRE?N`{r5mH@O5>{0MZ1ZLpx`@dQBi!<`if9VOeWWbj$qAWZj)=L z&;!|JW`5uK-E;3b!w4xQvpF2h@|Xjd11K__x^A2v5lzxT2Y|>h=xmWu9nTS3cA<#y z8VmUF2PVmDSBqRdYnD*TP48beyYR)sqGNVAAVirFCHc>i(&R$P9Y~Ebn6=n6xlmdM za%5kp3y%MheVs0p&H*7@MwH2d+iQtkD47HC%d}fMcwG3>BcjQ60PcmHu=-yELbd{k zhee0eh0pQ@lIl{qP*e?=A`A#2saAV3Z^~dFKrwAbK>$s^4JR8zW@>8O}XjKWN22-s;>AASDxS~t@3l;8c4b6HInSLjriX+lQC$E zC)i!Eh~M931At7EvC|J={2n_B0(}2O%8rAJ2~n^HP7ARou$|+Z4zkWp05=DC8jH}= znUKQ;ccC+GvDM$oNxMMg5})%R>rBYuScION13a~}_=4wv>BPqU)X#+YTSJWH6JM~E zFrBzH#F!n$Tk3^o0>Y|zrC!KfP8;^IMyL2YA)Z?muhfm2PTUFc+%Dpk+v(1P99|LR zsxAOk@!H-CO*h&uvQqUL|eZOx&lzvqSSlHs3>yE(aXt__dFe6<%s} z0Zb=3Y5)=8)ma16Nsbagwt=G5p*rj<74f^G%l`>;jp^l(U`y0000Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iyV; z5EC&Cl^>A+00Uu3L_t(&-tC$}OB+EH$6qqpt)OdIPi@kKN$oZY1)(B>f&_)&K?o@* zEjBm5L93SR!Rp0{L}Ju#x6c6p6pO``iHV6++W;tv z($mq=@uPCB>v{kHd~LIZIF5@}U-LZgiO1t}Z2>SmJd6-Rk=py6ot+=s0$^!rY2~{6 ztg2wYi|n(kg8eSC&$0^kCT9PEQTAC?p=kh%i;EF6&+$C(NhA`ZmII*4Y^hZGYAJwt zJU++syoX|myIEDRHR1;_)a=P z2qggk&d<+NU0q%KX5g*>D2md`77B&8!C>&O;ThmKE}GBhUt35# z0DxQ9_1VkI%a=EHqX!2EFMK{9=(=9CQs0jdvS%`x5CE(gRv??r7OZGo>Lv8b8Ne97 z3IqZlW@cudSqWf$eLa&(rQWNmx@owD2q9~dBxM2MlT{$oEkO-(&vDSl&P~iG zKJLO8JB`+hq8J2#c_siZm#f!=@Smb6ekOz*SAF~rV>}?sas*>MGCe)rD+mIA-Fs*) zZNon?RSO4zRYJ&ao#%D|U>9RN5RFC`#>U2;4-E}HtOXGS!NUxI5R$8Gfs2cad^(*z zNhXuujfB?$nUy4Ia(jC_QVWt!r%z}!QH>Tc#`75CFaW^e;o%>I&?;^7RU48dP3pQH z@p`?!GT;|N$Ql!XGQ>btCYut2gM-eqvom~pdYaQTjWDZ#732P|2Ca_&U#YjtAG_v- P00000NkvXXu0mjfe^;w- diff --git a/android/res/drawable-mdpi/or_launcher.png b/android/res/drawable-mdpi/or_launcher.png deleted file mode 100644 index 36a91549da9ef8ab264a645f5319272b46b749e2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4941 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 diff --git a/android/res/drawable-xhdpi/ic_menu_download.png b/android/res/drawable-xhdpi/ic_menu_download.png deleted file mode 100644 index fdbb334ef4a78d583e6a4fac0b4dc78bf5cd9776..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1167 zcmV;A1aSL_P)Px#0%A)?L;(MXkIcUS000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iyq~6BiS~ zbyM&F00a|BL_t(&-tCyrZyQAv$G>l8f7pp*w@uQJ{s?I$C=~~|6bX9afOT#>tX9nmhW@3YOjK!Ks*V^zFa zyPh*|c~|2EAa?9k-al<0>))qAa+@p@5C9B(q`%BsS$%=sV96*0W-ECm+2^EwvENGA z4BF1Kg5+B?1R7M8N?-$dwtlD&{UIV=DK zsfuChoj+Nx_YG=I41+&6PvxyFU(i)Qv@i}0z#viubD(VBNl#eN64#6q#oArE?9YM1 zYm(3a>&G)*Fvn&RX8L6=$#+*~bM~*^H3K?=B#Ht65Im!bkst9=`V79#Tes8{`#RD= zHyQwlR9Uh&e2&hSXi-h+a+L5t0svr>S0JmR_%FVUIf^*^BU@(2ehEm5?txk;U=F0W zsV)sTkavo9e(uH}mbMNO)?st74Jko$AMch;Z?I5~EOZe0zQEJ_`s(aR>ulDx4MkiHlGj3dz8*nd!n30PvPq?)?k3Eu431|2HJ|jqrGS hX3u)ov!4B@?Qaf{jjsO=vqt~`002ovPDHLkV1n!v0crpM diff --git a/android/res/drawable-xhdpi/ic_menu_info_details.png b/android/res/drawable-xhdpi/ic_menu_info_details.png deleted file mode 100644 index 24ea54373379a5b634333668fcab1aa99274f1e8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2763 zcmZ`*cQo6J7ypVBF=C6+rpBXa5v!i4*%(zdW2RL>jA+G3v?wAqYebc*9qUnB1>x1G zQllzrln!d9I%rGHsy^@i_xs~_?)lu$xu0`C=bn4c{o^LvTATB6OL7AMz<0p{Wq-s* z|AGsAlmU-+$D<7Lyl9RBekW2#x{oSIkcDgL5nKERv!MWkf5osMW8Wh-`VXHrcRh}@ zi3=!WwBOuXF6P?hDba-AEjzltfknBRUV3nwXJMdZNM9^iXkAu7GFjRfV_$I&g{Ig} z4vafFma{4ZOYPN?s`=xc>>Q1!N(JJoGdbUkagEz%YSmi>o(&eFE~Pevb{9T(k7^7) z&iwPNwW6BqrdH_o>(6hycU*lN-uI+21a%fqL*0H{0dv^IoI)Ue{kjOI<@&?Lgu$r2 z;_Ab#&wNH;AKHccy-9YH5cJki92|3c18jfzee0aqBc`lZK(Xbyi6liSAf@|C|XugY0jy^o5Rf1?ba7vJ21{c`c8tYstC%N}$BdGMM2GduH>)Z{Y5a53>|nO8)2 z6wu$VWE8FXao=lu7`H~yIya9T8~8Z`c<_$kdoEa2uRQtSOGUzlPzxBVzdt+3 z^GtF&HsO3op zy3Xm;fb3@*cQ!1w24w%v4{Kykv+;X>=11WKHQr!2QbO9U{* za-6VQA>%cuYXrO5(du}BFPq!8T$E>OcIB7GI9q1zXYm0Z0u{6LuH_^@-dRr8R!GC3 z1+(!!$?xbcO*Ve5Kbmc7P%ptmMo(Ja;V+ElI(!U%0&8<3BzG%c!foi^LKO_{C43p7 z4^lMU?n)YdzXols7SQ^7SZ%xNOgdXy^&*DzXZ{+hvi%aG`DQy3smi49WX?x$yU%HB zQbd!t-NSu|2P?`vtm~x{bm1=ffcCJHlOUSZ3N)@;@S0uR)5SHqcxZ>b&tn(yM)QZe z)Lyv0yh8}}FgkW)o6F~MT&{dUp!#;$exo$Ks*-|ueq!Kr#xyACGWxA|P|Y*mH(u?+ zW)1mzQ8<|rqvZY5=b44!-UoNTe;7q4tX`%O`#xwX|Kxn;;`UP1EBUU4J_X-#&% zt~ExUVdb^>HH+RXX1CjQlA;*TLUYoZXn9q4)49Hcer;UNg#-3}^s4c^HA&tmRlqfqkinHIh zUS5@s+q|(>H}yzQdNOz}s$u6$`Y=7hid!z0WWw~IuW2(y>?IM@=ZZBQYBOU${rxJB zd@7+}N4+oFmOK8olPPe;WxW~W7#A)mDbRdprtW#v6+n5B77w!L3`m$#LM`xWbXEwD ztlIJ)!;0y_wm1RXFL8Uejpx;^g9wn^Adbz`fTVqqu}(Kr2J{u-J^3lC#PKSc-K}54 zn>4%%Ww)X;gExzw$h6Qldyu=T(#>jyXT*1E>IA3C>qvH(&rhHVhAkC&gYm6S+Sk+G zHHbg;yb70iA5S7#d@kVZczCXqf7@ry9#tL|kta2a;Xt~+9BBeua5p`ZOmwkED&(kf zJFyq8tGsww2)9QO9?qp2xWGTwPZUiWW+|f`e?q=a9C8HW2=jyt1!@YDc?;~ZU}hU=EBk+UXM)VxTU#H>fJ6~J*ksvHZD%I*$^xa0RyjO zoR_eAU7f$${-7;f+8>hFtvwMmj9*BD7)_#8G4Fnq%!pel_6jTJC(h@Y+2RP!(cPDTR6%T&p&2dQp*f46{ZNa?M`^d-laMT)Y|YMuZ3S-5pswu2*0g?L zQ^oHuZQsGI#o!rC5^aHT5WZ5Uu46b`lw${)_dThdg+XifYB1_Pn$MBy+4&MzwmpB7 z=h_ChZz)UuF#nRDFBLQOC~BCtn>5!*%}y7yqa5=crj2>@bQ=Wa#Qc3IZId1;Y$y(g zPybwFSG=t91awA{nSh76xhJhb!Wb09XRa0`nbT#}9KqWCIMkNZ3}U#h{Wg5Pcq)si~=g&_N;) z{Brf}|6{mL@b>o!|Nn;QXt85Q28n+sI1qe@H?Sc%z}TDMiIcu?9qWs;$6>w0gNJbE Pj+%fArq-x>6A#KiIGGGZ diff --git a/android/res/drawable-xhdpi/ic_menu_preferences.png b/android/res/drawable-xhdpi/ic_menu_preferences.png deleted file mode 100644 index 02cfbad0b08d9276615ba7b25ca7f745dc3cfe4d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2507 zcmZ{mX*e5*7KXFgDW;;fqNt)pEU~sE1fjUZQYwfgvG0Z=&BU&ysI@4e)^SzG=nN*- z2914RtCXU(W*AE>tugcO{(A=8}ki#16T1 z0ItRE(n0R`O;CV~Byy+mxn-EFNK8XAdD4UFPH8I~#9`Pf<|LUQ&=6>lra z{kLk9Om05~DWGl1w%+mzaz>RoXhu zXamxDdlo9&D?C!_uN*S%F&I9~smJ2_w$jdRcTR1UP0>5z?*=)7OGR%IiRqijfn)cX zlVLAM=WuoOhrQ!{u89p$l}h?dCQIxVJE9vl95Lc+S?AZ5SB6w#hw!k*<5U4E3NH2| zd72shno|V6*&2#oV~attaJv4-=qH3}8LJI!sqg8A{p0IRY#O32jVXVCWVE&>+H@M) zcYfIEl+=#IchIxDl7-a~Z|3Ae+Q;j!kzv1S(JZlo)GT;WxPv(kUDwCsm{j%!%a_vx za~2169)ct@l+<IkP@)&0Fj$2W z%bslA#|jWSnX493IT^V zeq$p3ygpx5TU$CNK2g2WX$|6g@reVIF%`S|?(&*I0U!(cw8wC|(b03raR0GK-@%5a zB59BY7v;Xj8U*XON9K_GTFVu+-L+dDLWcN3=sULeYJ1QN3*qI}HnB+Imc^($`6Z<} zLCK8|^3Rce7M>@=>lFjGQ~`@o-a4Re`F-wM0omv9&xEfx#lLTV0|0UQlLplH&SYlO zD}4@<9gPKh()!(q6v-*iAX6)CAu?KW{lYOIQvf#$P{k>UgVg86wxA8h^4%K`UP|kD z%`5=q)+K*z54|Pz@kvaaUqUc2MY9{M_J)wD$}7y+v}Pg4^*(jiG;rlmbjwUi=#pen zp?($hZ-zhqOH~=*q|ck94iI*5 zKg@L!dG+AdPnM*iOnOSb4_tW?+9520g17@9^M*kiOVCewYv%x{x0}-PqI;3|soQx( z<9$Q0(TP)=-o2cjgdpXhFf$Qy1Kq(9n?|qPqnwP4;eHVu8Ka%NwkhuNdzUX7;19F& zrS!WC6&)I%Q4+ywbd3E@VX>@9x^w5u%F%o(e|ycL(h>_d55k{st7@@Na!vG?rm#Zf zpQusiT~w=Pgvn><9XKHR{#}RpOyg;NteMmgS13CSwX2|<8EIcCwapW1jq2CzHC#h# znGDADt3xdakx}w1&JDV>2L`G_2PMRsgZJFB&yZo%HdmnJo0f6MuGbCpdFG+O3~m&- zcl&S^C4am3+{x>ThPqR6pl%#{C!`cddzT}`n@)d%Jwgxg4iqg;>_8VvQWp5yoQ>f^ z>UYG~Ox{jp}K;cBa1VvZo%d`5>^(iaZIXnPuEdrOo}EnyVL2QkU)} z@#U(}wAHdBYsax*L{_dV(L&jTS<8GFlmP;#KjO?V-!YT^d`6C(x8VlzYo68_p zw}bf&!Di=))6k|gw{dEI#H{?|)zlLr+#cF!BxJHFHuc-9!?LPWC^nyaUS=AqnJ&!` z4UceO0|JA<(Xa7=t!hW*bh}kMfcJkNbw=NaPxDG>nq?ERjp0Pp^e&(LlJ@kXz`m^x zzUTgSVyuGR?a}NpX*pocm|h`ycM446BeyD)TQrFAj!~>v1`dy|7GR(DK9-n`$z3xl zXtu|>^hE*FZd$J9p{uvD5;#&zN`6nKF|M7a3Ig^in=hAN#;r4YcaM&Jx z^kZ`(-<-Mp3?cVZwjkX#uuWEGH204EwBJ>Wao98d0HCVxL7onuwi+pjR!QbUv`Xz# zPT$L5){!3fqYOr}=RCkK-~)-|djCr14@X%M=(9BA~*EF-}45q({ZOO&aM^j5#m=#@-*N@@n+} zkfZugdu8WV`PnLLtt|n60XVff?%|fFojNju{11sD7DQ7O^Ez{TzFdBJwsBdt4_0wUQ{VDPQmiN&K$Af9td7%QWSO z=WGO70W+FibHL@Fb2Hq?A>7j~9IxXMioXOv6{e!12vb*7)v$$W>!`tX)YKGVnmRBT zuXKIO{{#YpJbegJ|35$?39?)Ug#X!K6GRA)bPL4;ke)&AcuCU$H!nN}@8%g5(uco$ PIRr2@vP9Jz;Nt!U*I|wz diff --git a/android/res/drawable-xhdpi/ic_menu_save.png b/android/res/drawable-xhdpi/ic_menu_save.png deleted file mode 100644 index 62a66d87a53585e59db9cabb775a92cf023450cd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1546 zcmZ{kYd8}M7{`aH86xEF7$T!(Gc}gOX2WFeayf3(Yzqx-QwK$+!#Hv+xs*mSOu}(o zQdXJ=F$YIlH#y2}m5!s3TW9s{d^jKe|KIbz&-;J=-`;F*PgiBIE*Jm+D7z8xzEWbo z2?UfnfYfzd>ar)?UGadgS^2{P>7|RxSmNPZMkxe+C6YEhb_!d<8ZaGz=vd@SF)<` zSCmy(9e2TK!2{3H?ZXin%Zls*l1;_*+@mPmD!G;~Nh-bmo=8K6T_-Z0r`@RKP4UyV z-`x+q(;X>q8T9bB>i(5(4jnrblBq4*Jcb53gF=@{%Y{lm6hmYETZk#DJ}^9~R8yop zxCiCQmSxW$6ckb$S-}yHkDNi^F$sf|wXAKcx88*0F#E;>{YjIT%o0t&+V_|*ny&?w zPpGyTUA4Ghg4NO#3muLYHG(aw%SX&ECHV6;_@nL^SgT)u#MDM|y%Pjp<5(8Ri`s%E z&DW}@-%k5TrRRg$jJx))8+uy5kdgvm>1$h&e&tGzVrGxZFX6J+S|Zy*Q@Zbo5|@aI zF1^bm8}iB~_SaAS^t;Qx=#N~BnMb{x%KrQcgPtE(aq7Ae-p`6xj~n42`;NI>1{m9_ z(bF5mO^7EgUC(!xafwdzdHoFG51nx?pgnzVPTZy&oM`=80a!=Ysp39%@31KMy-!G$ zkP~7ISb!5Y^B|xS%;9rU=iUtUSd`8NefElw*KoeYwDVamI&1^1U*s{kW7nFCi9uH= z`g%*Meru_Him-(=r^=1o|WPIri&R^g$=dl z2gS)%nwdz00+#c%8Vu7WxoL9rn2Zu1$HH|I;z;1Or*mMt4+b$z52gahRHVm5C4VyI zg09-dWFV4WeYQsKMnqcYQmb#N%6L^DD3<$kxH)G=Ni%5W^Ez_GUEo%<{*Ieh64 zg_@^xGJQJk6Q>TnrRBC;#F^M(RL9XTL)Fy0q;$6HOuUW{YToW&%iP)ss>{>9v{QYBpw@h zebH7HZPiZ{3C#g@<+02fNw)1ZGN`U}(ejTjhsuVaV=+*R;;1aqW+Y z;0x=|1U+{{Nx?ZN-lJW^Bnc+l{hc8Gwj~B|mYzEDUXP$_d~0GdBtOgeI)Yjq7bbGO zNcZ#tL8GCsTK^^$E^2vHT=pG+atA*&$|wzZe%;X~7tPajW;Mi%dyAK!U&UFrl3s1o1%+={unkMr^Ng1D72}N4*t$;^o zI|Kpe>jMfoXkCRqf}dlz+H-a<{vjEYt^G zJiu9DjvU*y_!a#aM#S7p+5mlNPt0a_mE04Syrs6r&hGIm8Z9KyCoSolG-Wvlv7#bb z6f~JZkpf^1M<8Hu8<_PGf4ChQc^HjE!r&-09Ij&0)b*bLJw7U$n)LsH)KpD*X+Y;& sgI_$AbvBYg0brxzPf#Fk^hg@Tml7G3bb63tFFgXdIeX%poJj0{0c&xt=Kufz diff --git a/android/res/drawable-xhdpi/or_launcher.png b/android/res/drawable-xhdpi/or_launcher.png deleted file mode 100644 index f13148d214873f711c408b17983f36997060ad51..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16057 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 - - - - - - \ No newline at end of file diff --git a/android/res/drawable/openrocket.png b/android/res/drawable/openrocket.png deleted file mode 100644 index ca28bf5bb55acc79109fd7eb7409a62a6bf077f2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22753 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 diff --git a/android/res/drawable/rocketglobe.png b/android/res/drawable/rocketglobe.png deleted file mode 100644 index 6deb572b866302e8e5dc17cdd08d550b6662ff79..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 123979 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�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

RbpmrpS9N%qof>UcnxPovnh;A?$j}ZGMfb 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%0D)`(}VNKSvnzR^nE*^I^Thw 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%0Dc^XJ@uR;?lpE*GN{@ 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 V^F8yJ5#9g*002ovPDHLkV1h2h9J2rb diff --git a/android/res/drawable/sf_donate.png b/android/res/drawable/sf_donate.png deleted file mode 100644 index 7f5a52c5976964e8ce90d962820be4099a2e5201..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8378 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 - - - - - \ No newline at end of file diff --git a/android/res/drawable/simulation_state_green.xml b/android/res/drawable/simulation_state_green.xml deleted file mode 100644 index 4ccef1898..000000000 --- a/android/res/drawable/simulation_state_green.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/android/res/drawable/simulation_state_red.xml b/android/res/drawable/simulation_state_red.xml deleted file mode 100644 index 37c5b523f..000000000 --- a/android/res/drawable/simulation_state_red.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/android/res/drawable/simulation_state_yellow.xml b/android/res/drawable/simulation_state_yellow.xml deleted file mode 100644 index 1d2584784..000000000 --- a/android/res/drawable/simulation_state_yellow.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/android/res/drawable/starfield.png b/android/res/drawable/starfield.png deleted file mode 100644 index 6ce43c533bb1ed1ceb0a84449d906a409e8f503e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 65403 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 - - - - - - - - - - - - -