Commit 56679c1c authored by Sajal Narang's avatar Sajal Narang Committed by GitHub

Merge pull request #149 from pulsejet/map

InstiMap!
parents 86254a47 f2966a19
...@@ -14,6 +14,7 @@ import app.insti.data.Notification; ...@@ -14,6 +14,7 @@ import app.insti.data.Notification;
import app.insti.data.PlacementBlogPost; import app.insti.data.PlacementBlogPost;
import app.insti.data.TrainingBlogPost; import app.insti.data.TrainingBlogPost;
import app.insti.data.User; import app.insti.data.User;
import app.insti.data.Venue;
import retrofit2.Call; import retrofit2.Call;
import retrofit2.http.Body; import retrofit2.http.Body;
import retrofit2.http.GET; import retrofit2.http.GET;
...@@ -38,6 +39,9 @@ public interface RetrofitInterface { ...@@ -38,6 +39,9 @@ public interface RetrofitInterface {
@GET("events") @GET("events")
Call<NewsFeedResponse> getNewsFeed(@Header("Cookie") String sessionId); Call<NewsFeedResponse> getNewsFeed(@Header("Cookie") String sessionId);
@GET("locations")
Call<List<Venue>> getAllVenues();
@GET("events") @GET("events")
Call<NewsFeedResponse> getEventsBetweenDates(@Header("Cookie") String sessionId, @Query("start") String start, @Query("end") String end); Call<NewsFeedResponse> getEventsBetweenDates(@Header("Cookie") String sessionId, @Query("start") String start, @Query("end") String end);
......
...@@ -145,7 +145,7 @@ public class CalendarFragment extends BaseFragment { ...@@ -145,7 +145,7 @@ public class CalendarFragment extends BaseFragment {
private void showEventsForDate(Date date) { private void showEventsForDate(Date date) {
/* Skip if we're already destroyed */ /* Skip if we're already destroyed */
if (getActivity() == null) return; if (getActivity() == null || getView() == null) return;
final List<Event> filteredEvents = new ArrayList<Event>(); final List<Event> filteredEvents = new ArrayList<Event>();
for (Event event : events) { for (Event event : events) {
......
...@@ -128,7 +128,7 @@ public class FeedFragment extends BaseFragment { ...@@ -128,7 +128,7 @@ public class FeedFragment extends BaseFragment {
private void displayEvents(final List<Event> events) { private void displayEvents(final List<Event> events) {
/* Skip if we're already destroyed */ /* Skip if we're already destroyed */
if (getActivity() == null) return; if (getActivity() == null || getView() == null) return;
final FeedAdapter feedAdapter = new FeedAdapter(events, new ItemClickListener() { final FeedAdapter feedAdapter = new FeedAdapter(events, new ItemClickListener() {
@Override @Override
......
...@@ -146,7 +146,7 @@ public class MessMenuFragment extends BaseFragment { ...@@ -146,7 +146,7 @@ public class MessMenuFragment extends BaseFragment {
private void displayMessMenu(HostelMessMenu hostelMessMenu) { private void displayMessMenu(HostelMessMenu hostelMessMenu) {
/* Skip if we're already destroyed */ /* Skip if we're already destroyed */
if (getActivity() == null) return; if (getActivity() == null || getView() == null) return;
List<MessMenu> messMenus = hostelMessMenu.getMessMenus(); List<MessMenu> messMenus = hostelMessMenu.getMessMenus();
......
...@@ -98,7 +98,7 @@ public class MyEventsFragment extends BaseFragment { ...@@ -98,7 +98,7 @@ public class MyEventsFragment extends BaseFragment {
private void displayEvents(final List<Event> events) { private void displayEvents(final List<Event> events) {
/* Check if already destroyed */ /* Check if already destroyed */
if (getActivity() == null) return; if (getActivity() == null || getView() == null) return;
final FeedAdapter feedAdapter = new FeedAdapter(events, new ItemClickListener() { final FeedAdapter feedAdapter = new FeedAdapter(events, new ItemClickListener() {
@Override @Override
......
...@@ -99,7 +99,7 @@ public class NewsFragment extends BaseFragment { ...@@ -99,7 +99,7 @@ public class NewsFragment extends BaseFragment {
private void displayNews(final List<NewsArticle> result) { private void displayNews(final List<NewsArticle> result) {
/* Skip if we're already destroyed */ /* Skip if we're already destroyed */
if (getActivity() == null) return; if (getActivity() == null || getView() == null) return;
final NewsAdapter newsAdapter = new NewsAdapter(result, new ItemClickListener() { final NewsAdapter newsAdapter = new NewsAdapter(result, new ItemClickListener() {
@Override @Override
......
...@@ -100,7 +100,7 @@ public class PlacementBlogFragment extends BaseFragment { ...@@ -100,7 +100,7 @@ public class PlacementBlogFragment extends BaseFragment {
private void displayPlacementFeed(final List<PlacementBlogPost> result) { private void displayPlacementFeed(final List<PlacementBlogPost> result) {
/* Skip if we're already destroyed */ /* Skip if we're already destroyed */
if (getActivity() == null) return; if (getActivity() == null || getView() == null) return;
final PlacementBlogAdapter placementBlogAdapter = new PlacementBlogAdapter(result, new ItemClickListener() { final PlacementBlogAdapter placementBlogAdapter = new PlacementBlogAdapter(result, new ItemClickListener() {
@Override @Override
......
...@@ -100,7 +100,7 @@ public class TrainingBlogFragment extends BaseFragment { ...@@ -100,7 +100,7 @@ public class TrainingBlogFragment extends BaseFragment {
private void displayTrainingFeed(final List<TrainingBlogPost> result) { private void displayTrainingFeed(final List<TrainingBlogPost> result) {
/* Skip if we're already destroyed */ /* Skip if we're already destroyed */
if (getActivity() == null) return; if (getActivity() == null || getView() == null) return;
final TrainingBlogAdapter trainingBlogAdapter = new TrainingBlogAdapter(result, new ItemClickListener() { final TrainingBlogAdapter trainingBlogAdapter = new TrainingBlogAdapter(result, new ItemClickListener() {
@Override @Override
......
package com.mrane.campusmap;
import android.content.Context;
import android.graphics.Typeface;
import android.graphics.drawable.ColorDrawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.mrane.data.Marker;
import java.util.HashMap;
import java.util.List;
import app.insti.R;
import app.insti.fragment.MapFragment;
public class ExpandableListAdapter extends BaseExpandableListAdapter {
private Context _context;
private List<String> _listDataHeader;
private HashMap<String, List<String>> _listDataChild;
public ExpandableListAdapter(Context context, List<String> listDataHeader,
HashMap<String, List<String>> listChildData) {
this._context = context;
this._listDataHeader = listDataHeader;
this._listDataChild = listChildData;
}
@Override
public Object getChild(int groupPosition, int childPosititon) {
return this._listDataChild.get(this._listDataHeader.get(groupPosition))
.get(childPosititon);
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
@Override
public View getChildView(int groupPosition, final int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
String headerTitle = (String) getGroup(groupPosition);
final String childText = (String) getChild(groupPosition, childPosition);
if (convertView == null) {
LayoutInflater infalInflater = (LayoutInflater) this._context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(R.layout.map_list_item, null);
}
TextView txtListChild = (TextView) convertView
.findViewById(R.id.lblListItem);
View itemGroupColor = (View) convertView.findViewById(R.id.item_group_color);
int color = Marker.getColor(Marker.getGroupId(headerTitle));
itemGroupColor.setBackgroundColor(color);
Typeface regular = Typeface.createFromAsset(_context.getAssets(), MapFragment.FONT_REGULAR);
txtListChild.setTypeface(regular);
txtListChild.setText(childText);
return convertView;
}
@Override
public int getChildrenCount(int groupPosition) {
return this._listDataChild.get(this._listDataHeader.get(groupPosition))
.size();
}
@Override
public Object getGroup(int groupPosition) {
return this._listDataHeader.get(groupPosition);
}
@Override
public int getGroupCount() {
return this._listDataHeader.size();
}
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
String headerTitle = (String) getGroup(groupPosition);
if (convertView == null) {
LayoutInflater infalInflater = (LayoutInflater) this._context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(
R.layout.map_expandable_list_header, null);
}
TextView lblListHeader = (TextView) convertView
.findViewById(R.id.lblListHeader);
Typeface regular = Typeface.createFromAsset(_context.getAssets(), MapFragment.FONT_REGULAR);
lblListHeader.setTypeface(regular);
lblListHeader.setText(headerTitle);
ImageView iconExpand = (ImageView) convertView
.findViewById(R.id.icon_expand);
ImageView groupColor = (ImageView) convertView.findViewById(R.id.group_color);
int color = Marker.getColor(Marker.getGroupId(headerTitle));
groupColor.setImageDrawable(new ColorDrawable(color));
if (isExpanded) {
iconExpand.setImageResource(R.drawable.ic_action_expand);
} else {
iconExpand.setImageResource(R.drawable.ic_action_next_item);
}
return convertView;
}
@Override
public boolean hasStableIds() {
return false;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
}
package com.mrane.campusmap;
import android.content.Context;
import android.graphics.Typeface;
import android.text.Html;
import android.text.Spanned;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.mrane.data.Marker;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;
import app.insti.R;
import app.insti.fragment.MapFragment;
public class FuzzySearchAdapter extends BaseAdapter {
Context mContext;
LayoutInflater inflater;
private List<Marker> resultlist = null;
private ArrayList<Marker> inputlist;
private List<ScoredMarker> map;
private Locale l;
private String searchedText = "";
private SettingsManager settingsManager;
private boolean turnOnResidences;
public FuzzySearchAdapter(Context context, List<Marker> inputlist) {
mContext = context;
l = Locale.getDefault();
this.resultlist = inputlist;
Collections.sort(resultlist, new MarkerNameComparator());
inflater = LayoutInflater.from(mContext);
this.inputlist = new ArrayList<Marker>();
this.inputlist.addAll(resultlist);
map = new ArrayList<ScoredMarker>();
}
public class ViewHolder {
TextView label;
LinearLayout rowContainer;
}
public class ScoredMarker {
Marker m;
int score;
public ScoredMarker(int score, Marker m) {
this.m = m;
this.score = score;
}
}
public int getResultSize() {
return resultlist.size();
}
@Override
public int getCount() {
if (this.getResultSize() == 0) {
return 1;
}
return resultlist.size();
}
@Override
public Marker getItem(int position) {
return resultlist.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View view, ViewGroup parent) {
final ViewHolder holder;
if (view == null) {
holder = new ViewHolder();
view = inflater.inflate(R.layout.map_row_layout, null);
holder.label = (TextView) view.findViewById(R.id.label);
Typeface regular = Typeface.createFromAsset(mContext.getAssets(),
MapFragment.FONT_REGULAR);
holder.label.setTypeface(regular);
holder.rowContainer = (LinearLayout) view
.findViewById(R.id.row_container);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
// Set the results into TextViews
if (this.getResultSize() == 0) {
if (settingsManager.showResidences()) {
holder.label.setText("Sorry, no results found.");
} else {
if (turnOnResidences) {
holder.label
.setText("There are results in residences. Select show residences from settings.");
} else {
holder.label.setText("Sorry, no results found.");
}
}
} else {
holder.label.setText(getSpannedText(resultlist.get(position)
.getName(), searchedText));
}
return view;
}
private Spanned getSpannedText(String name, String searchedText2) {
String smallLetterName = name.toLowerCase(l);
searchedText2 = searchedText2.toLowerCase(l).replaceAll("\\s", "");
if (searchedText2.equals("")) {
return Html.fromHtml(name);
} else {
String htmlName = "";
if (isShortForm(smallLetterName, searchedText2)) {
htmlName = getHighlightedShortform(name, searchedText2);
} else {
int i = 0;
int j = 0;
while (i < searchedText2.length()) {
if (smallLetterName.charAt(j) == searchedText2.charAt(i)) {
htmlName += "<b>" + name.charAt(j) + "</b>";
i++;
j++;
} else {
htmlName += name.charAt(j);
j++;
}
}
if (j < name.length()) {
htmlName += name.substring(j, name.length());
}
}
return Html.fromHtml(htmlName);
}
}
private String getHighlightedShortform(String name, String searchedText2) {
String smallCapsName = name.toLowerCase(l);
String possibleShortform = "";
for (int i = 0; i < searchedText2.length(); i++) {
possibleShortform = "";
for (int j = 0; j < searchedText2.length(); j++) {
if (j <= i) {
possibleShortform += searchedText2.charAt(j);
} else {
possibleShortform += "(.*)" + " " + searchedText2.charAt(j);
}
}
possibleShortform += "(.*)";
if (smallCapsName.matches(possibleShortform)) {
name = makeBold(name, searchedText2.substring(0, i + 1));
i++;
while (i < searchedText2.length()) {
name = makeBold(name, " " + searchedText2.charAt(i));
i++;
}
}
}
return name;
}
private String makeBold(String name, String substring) {
String smallCapsName = name.toLowerCase(l);
int firstIndex = smallCapsName.indexOf(substring);
if (name.charAt(firstIndex) == ' ') {
name = name.substring(0, firstIndex + 1)
+ "<b>"
+ name.substring(firstIndex + 1,
firstIndex + substring.length())
+ "</b>"
+ name.substring(firstIndex + substring.length(),
name.length());
} else {
name = name.substring(0, firstIndex)
+ "<b>"
+ name.substring(firstIndex,
firstIndex + substring.length())
+ "</b>"
+ name.substring(firstIndex + substring.length(),
name.length());
}
return name;
}
public void filter(String charText) {
turnOnResidences = false;
charText = charText.toLowerCase(Locale.getDefault());
searchedText = charText;
resultlist.clear();
map.clear();
if (charText.length() == 0) {
if (settingsManager.showResidences()) {
resultlist.addAll(inputlist);
} else {
for (Marker m : inputlist) {
if (m.getGroupIndex() != Marker.RESIDENCES) {
resultlist.add(m);
}
}
}
} else if (charText.length() > 10) {
for (Marker m : inputlist) {
if (m.getName().toLowerCase(Locale.getDefault())
.contains(charText)) {
if (settingsManager.showResidences()) {
resultlist.add(m);
} else {
if (m.getGroupIndex() != Marker.RESIDENCES) {
resultlist.add(m);
} else {
turnOnResidences = true;
}
}
}
}
} else {
for (Marker m : inputlist) {
int score = checkModifyMarker(m, charText);
if (score != 0) {
if (settingsManager.showResidences()) {
map.add(new ScoredMarker(score, m));
} else {
if (m.getGroupIndex() != Marker.RESIDENCES) {
map.add(new ScoredMarker(score, m));
} else {
turnOnResidences = true;
}
}
}
}
resultlist = sortByScore(map);
}
notifyDataSetChanged();
}
private List<Marker> sortByScore(List<ScoredMarker> tempScore) {
List<Marker> templist = new ArrayList<Marker>();
Collections.sort(tempScore, new MarkerScoreComparator());
for (ScoredMarker k : tempScore) {
templist.add(k.m);
}
return templist;
}
private int checkModifyMarker(Marker m, String charText) {
int tempScore = 5;
String tempCharText = "(.*)";
for (int i = 0; i < charText.length(); i++) {
tempCharText += charText.charAt(i) + "(.*)";
}
if (m.getName().toLowerCase(l).matches(tempCharText)) {
boolean b = false;
if (m.getName().toLowerCase(l).startsWith(charText)) {
return 1;
}
if (isShortForm(m.getName(), charText)) {
return 2;
}
for (String s : m.getName().split(" ")) {
b = b || s.toLowerCase(l).startsWith("" + charText.charAt(0));
if (!b) {
tempScore += 10;
}
if (s.startsWith(charText)) {
return 3;
}
}
if (b) {
return tempScore;
} else {
return 0;
}
} else {
return 0;
}
}
private boolean isShortForm(String name, String charText) {
name = name.toLowerCase(l);
charText = charText.toLowerCase(l).replaceAll("\\s", "");
String possibleShortform = "";
for (int i = 0; i < charText.length(); i++) {
possibleShortform = "";
for (int j = 0; j < charText.length(); j++) {
if (j <= i) {
possibleShortform += charText.charAt(j);
} else {
possibleShortform += "(.*)" + " " + charText.charAt(j);
}
}
possibleShortform += "(.*)";
if (name.matches(possibleShortform)) {
return true;
}
}
return false;
}
public SettingsManager getSettingsManager() {
return settingsManager;
}
public void setSettingsManager(SettingsManager settingsManager) {
this.settingsManager = settingsManager;
}
public class MarkerScoreComparator implements Comparator<ScoredMarker> {
public int compare(ScoredMarker m1, ScoredMarker m2) {
return m1.score - m2.score;
}
}
public class MarkerNameComparator implements Comparator<Marker> {
public int compare(Marker m1, Marker m2) {
return m1.getName().toLowerCase(l)
.compareTo(m2.getName().toLowerCase(l));
}
}
}
package com.mrane.campusmap;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.OnGroupClickListener;
import android.widget.ExpandableListView.OnGroupCollapseListener;
import android.widget.ExpandableListView.OnGroupExpandListener;
import com.mrane.data.Marker;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import app.insti.R;
import app.insti.fragment.MapFragment;
public class IndexFragment extends Fragment implements OnGroupExpandListener,
OnGroupCollapseListener, OnGroupClickListener {
MapFragment mainActivity;
ExpandableListAdapter adapter;
HashMap<String, Marker> data;
View rootView;
ExpandableListView list;
List<String> headers = new ArrayList<String>();
HashMap<String, List<String>> childData = new HashMap<String, List<String>>();
int pos;
int prevGroup = -1;
public IndexFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mainActivity = MapFragment.getMainActivity();
data = mainActivity.data;
if (headers.isEmpty()) {
setHeaderAndChildData();
}
adapter = new ExpandableListAdapter(mainActivity.getContext(), headers, childData);
rootView = inflater.inflate(R.layout.map_index_fragment, container, false);
list = (ExpandableListView) rootView.findViewById(R.id.index_list);
mainActivity.setExpAdapter(adapter);
list.setAdapter(adapter);
list.setOnChildClickListener(mainActivity);
list.setOnGroupExpandListener(this);
list.setOnGroupCollapseListener(this);
list.setOnGroupClickListener(this);
return rootView;
}
@Override
public void onResume() {
String name = mainActivity.editText.getText().toString();
if(name.isEmpty()) {
collapseAllGroups();
list.setSelectedGroup(0);
} else {
if(data.containsKey(name)) {
String groupName = data.get(name).getGroupName();
int groupId = getGroupId(groupName);
if(groupId != -1) {
list.expandGroup(groupId);
list.setSelectedGroup(groupId);
}
}
}
super.onResume();
}
private int getGroupId(String groupName) {
int groupCount = adapter.getGroupCount();
int temp = -1;
for (int i=0; i < groupCount; i++) {
if(adapter.getGroup(i).equals(groupName)) {
temp = i;
}
}
return temp;
}
private void collapseAllGroups() {
int groupCount = adapter.getGroupCount();
for (int i=0; i < groupCount; i++) {
list.collapseGroup(i);
}
}
private void setChildData() {
Collection<Marker> keys = data.values();
for (Marker key : keys) {
List<String> child = childData.get(key.getGroupName());
child.add(key.getName());
}
sortChildData();
}
private void sortChildData() {
for (String header : headers) {
List<String> child = childData.get(header);
Collections.sort(child);
}
}
private void setHeaderAndChildData() {
String[] headerString = Marker.getGroupNames();
Collections.addAll(headers, headerString);
for (String header : headers) {
childData.put(header, new ArrayList<String>());
}
setChildData();
}
@Override
public void onGroupExpand(int groupPosition) {
if (prevGroup != -1 && prevGroup != groupPosition) {
list.collapseGroup(prevGroup);
}
prevGroup = groupPosition;
}
@Override
public void onGroupCollapse(int groupPosition) {
if (prevGroup != -1) {
//list.setSelectionFromTop(prevGroup, 0);
}
}
@Override
public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition,
long id) {
// Implement this method to scroll to the correct position as this doesn't
// happen automatically if we override onGroupExpand() as above
parent.smoothScrollToPosition(groupPosition);
// Need default behaviour here otherwise group does not get expanded/collapsed
// on click
if (parent.isGroupExpanded(groupPosition)) {
parent.collapseGroup(groupPosition);
} else {
parent.expandGroup(groupPosition);
}
return true;
}
}
package com.mrane.campusmap;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import com.mrane.data.Marker;
import java.util.HashMap;
import app.insti.R;
import app.insti.fragment.MapFragment;
public class ListFragment extends Fragment {
MapFragment mainActivity;
FuzzySearchAdapter adapter;
HashMap<String, Marker> data;
View rootView;
ListView list;
public ListFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mainActivity = MapFragment.getMainActivity();
adapter = mainActivity.getAdapter();
rootView = inflater.inflate(R.layout.map_list_fragment, container, false);
list = (ListView) rootView.findViewById(R.id.suggestion_list);
list.setAdapter(adapter);
list.setOnItemClickListener(mainActivity);
list.setOnTouchListener(mainActivity);
list.setFastScrollEnabled(true);
return rootView;
}
}
package com.mrane.campusmap;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.content.res.Resources;
import android.preference.PreferenceManager;
import app.insti.R;
public class SettingsManager implements OnSharedPreferenceChangeListener{
private SharedPreferences sharedPrefs;
private String muteKey;
private String residencesKey;
private String lastUpdatedKey;
public SettingsManager(Context context){
sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context);
sharedPrefs.registerOnSharedPreferenceChangeListener(this);
Resources res = context.getResources();
muteKey = "mute";
residencesKey = "residences";
lastUpdatedKey = "lastupdated";
}
public boolean isMuted(){
return sharedPrefs.getBoolean(muteKey, false);
}
public boolean showResidences(){
return sharedPrefs.getBoolean(residencesKey, true);
}
public long getLastUpdatedOn() {
return sharedPrefs.getLong(lastUpdatedKey, 0);
}
public void setLastUpdatedOn(long lastUpdatedOn) {
sharedPrefs.edit().putLong(lastUpdatedKey, lastUpdatedOn).commit();
}
@Override
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
}
}
package com.mrane.data;
public class Building extends Marker {
public String[] children;
public Building(String name, String shortName, float x, float y,
int groupIndex, String[] children, String description) {
super(name, shortName, x, y, groupIndex, description);
this.children = children;
}
public String[] getChildren() {
return children;
}
public void setChildren(String[] children) {
this.children = children;
}
}
package com.mrane.data;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import app.insti.data.Venue;
public class Locations {
public HashMap<String, Marker> data = new HashMap<String, Marker>();
public Locations(List<Venue> venueList) {
// Add locations
for (Venue venue : venueList) {
Marker marker;
// Skip bad locations
if (venue.getVenuePixelX() == 0 || venue.getVenueGroupId() == null) {
continue;
}
// Set some things up
if (venue.getVenueParentRelation() == null) {
venue.setVenueParentRelation("");
}
if (venue.getVenueParentRelation() == null || venue.getVenueParentRelation().equals("")) {
// Add children
final List<String> children = new ArrayList();
for (Venue child : venueList) {
if (child.getVenueParentId() != null && child.getVenueParentId().equals(venue.getVenueID())) {
children.add(child.getVenueName());
}
}
String[] childArray = new String[children.size()];
marker = new Building(
venue.getVenueName(), venue.getVenueShortName(), venue.getVenuePixelX(), venue.getVenuePixelY(),
venue.getVenueGroupId(), children.toArray(childArray), venue.getVenueDescripion());
} else {
// Get parent name
String parentName = "";
for (Venue parent : venueList) {
if (parent.getVenueID().equals(venue.getVenueParentId())) {
parentName = parent.getVenueName();
break;
}
}
marker = new Room(venue.getVenueName(), venue.getVenueShortName(), venue.getVenuePixelX(), venue.getVenuePixelY(),
venue.getVenueGroupId(), parentName, venue.getVenueParentRelation(), venue.getVenueDescripion());
}
data.put(marker.getName(), marker);
}
}
}
\ No newline at end of file
package com.mrane.data;
import android.graphics.Color;
import android.graphics.PointF;
import java.util.ArrayList;
import java.util.Arrays;
public class Marker {
private int id;
private String name;
private String shortName;
private PointF point;
private int groupIndex;
private boolean showDefault;
private String description;
private String tag;
private String imageUri;
private int parentId;
private String parentRel;
private int[] childIds;
private long lat;
private long lng;
public static final int COLOR_BLUE = Color.rgb(75, 186, 238);
public static final int COLOR_YELLOW = Color.rgb(255, 186, 0);
public static final int COLOR_GREEN = Color.rgb(162, 208, 104);
public static final int COLOR_GRAY = Color.rgb(156, 156, 156);
public static final int DEPARTMENTS = 1;
public static final int HOSTELS = 2;
public static final int RESIDENCES = 3;
public static final int HALLS_N_AUDITORIUMS = 4;
public static final int FOOD_STALLS = 5;
public static final int BANKS_N_ATMS = 6;
public static final int SCHOOLS = 7;
public static final int SPORTS = 8;
public static final int OTHERS = 9;
public static final int GATES = 10;
public static final int PRINT = 11;
public static final int LABS = 12;
private static final String DEPARTMENTS_NAME = "Departments";
private static final String HOSTELS_NAME = "Hostels";
private static final String RESIDENCES_NAME = "Residences";
private static final String HALLS_N_AUDITORIUMS_NAME = "Halls and Auditoriums";
private static final String FOOD_STALLS_NAME = "Food Stalls";
private static final String BANKS_N_ATMS_NAME = "Banks and Atms";
private static final String SCHOOLS_NAME = "Schools";
private static final String SPORTS_NAME = "Sports";
private static final String OTHERS_NAME = "Others";
private static final String GATES_NAME = "Gates";
private static final String PRINT_NAME = "Printer facility";
private static final String LABS_NAME = "Labs";
public Marker(String name, String shortName, float x, float y,
int groupIndex, String description) {
this.setPoint(new PointF(x, y));
this.groupIndex = groupIndex;
this.setName(name);
this.setShortName(shortName);
this.setShowDefault(false);
this.setDescription(description);
this.setImageUri("");
}
public Marker(int id, String name, String shortName, float pixelX, float pixelY,
int groupIndex, String description, int parentId, String parentRel,
int[] childIds, long lat, long lng) {
this.id = id;
this.name = name;
this.shortName = shortName;
this.point = new PointF(pixelX, pixelY);
this.groupIndex = groupIndex;
this.description = description;
this.setParentId(parentId);
this.setParentRel(parentRel);
this.setChildIds(childIds);
this.setLat(lat);
this.setLng(lng);
}
public static int getColor(int group) {
Integer[] yellowGroup = new Integer[] { HOSTELS };
Integer[] blueGroup = new Integer[] { DEPARTMENTS, LABS,
HALLS_N_AUDITORIUMS };
Integer[] greenGroup = new Integer[] { RESIDENCES };
Integer[] purpleGroup = new Integer[] { FOOD_STALLS, BANKS_N_ATMS,
SCHOOLS, SPORTS, OTHERS, GATES, PRINT };
ArrayList<Integer> yellowList = new ArrayList<Integer>(
Arrays.asList(yellowGroup));
ArrayList<Integer> blueList = new ArrayList<Integer>(
Arrays.asList(blueGroup));
ArrayList<Integer> greenList = new ArrayList<Integer>(
Arrays.asList(greenGroup));
ArrayList<Integer> purpleList = new ArrayList<Integer>(
Arrays.asList(purpleGroup));
if (yellowList.contains(group)) {
return COLOR_YELLOW;
} else if (blueList.contains(group)) {
return COLOR_BLUE;
} else if (greenList.contains(group)) {
return COLOR_GREEN;
} else if (purpleList.contains(group)) {
return COLOR_GRAY;
}
return 0;
}
public int getColor() {
int group = this.groupIndex;
return getColor(group);
}
public String getGroupName() {
switch (groupIndex) {
case DEPARTMENTS:
return DEPARTMENTS_NAME;
case HOSTELS:
return HOSTELS_NAME;
case RESIDENCES:
return RESIDENCES_NAME;
case HALLS_N_AUDITORIUMS:
return HALLS_N_AUDITORIUMS_NAME;
case FOOD_STALLS:
return FOOD_STALLS_NAME;
case BANKS_N_ATMS:
return BANKS_N_ATMS_NAME;
case SCHOOLS:
return SCHOOLS_NAME;
case SPORTS:
return SPORTS_NAME;
case OTHERS:
return OTHERS_NAME;
case GATES:
return GATES_NAME;
case PRINT:
return PRINT_NAME;
case LABS:
return LABS_NAME;
}
return "";
}
public static String[] getGroupNames() {
String[] groupNames = { DEPARTMENTS_NAME, LABS_NAME,
HALLS_N_AUDITORIUMS_NAME, HOSTELS_NAME, RESIDENCES_NAME,
FOOD_STALLS_NAME, BANKS_N_ATMS_NAME, SCHOOLS_NAME, SPORTS_NAME,
PRINT_NAME, GATES_NAME, OTHERS_NAME };
return groupNames;
}
public static int getGroupId(String groupName) {
int result = 0;
if (groupName.equals(DEPARTMENTS_NAME))
result = DEPARTMENTS;
if (groupName.equals(HOSTELS_NAME))
result = HOSTELS;
if (groupName.equals(RESIDENCES_NAME))
result = RESIDENCES;
if (groupName.equals(HALLS_N_AUDITORIUMS_NAME))
result = HALLS_N_AUDITORIUMS;
if (groupName.equals(FOOD_STALLS_NAME))
result = FOOD_STALLS;
if (groupName.equals(BANKS_N_ATMS_NAME))
result = BANKS_N_ATMS;
if (groupName.equals(SCHOOLS_NAME))
result = SCHOOLS;
if (groupName.equals(SPORTS_NAME))
result = SPORTS;
if (groupName.equals(OTHERS_NAME))
result = OTHERS;
if (groupName.equals(GATES_NAME))
result = GATES;
if (groupName.equals(PRINT_NAME))
result = PRINT;
if (groupName.equals(LABS_NAME))
result = LABS;
return result;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getShortName() {
return shortName;
}
public void setShortName(String shortName) {
this.shortName = shortName;
}
public PointF getPoint() {
return point;
}
public void setPoint(PointF point) {
this.point = point;
}
public int getGroupIndex() {
return groupIndex;
}
public void setGroupIndex(int groupIndex) {
this.groupIndex = groupIndex;
}
public boolean isShowDefault() {
return showDefault;
}
public void setShowDefault(boolean showDefault) {
this.showDefault = showDefault;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getTag() {
return tag;
}
public void setTag(String tag) {
this.tag = tag;
}
public String getImageUri() {
return imageUri;
}
public void setImageUri(String imageUri) {
this.imageUri = imageUri;
}
public int[] getChildIds() {
return childIds;
}
public void setChildIds(int[] childIds) {
this.childIds = childIds;
}
public int getParentId() {
return parentId;
}
public void setParentId(int parentId) {
this.parentId = parentId;
}
public String getParentRel() {
return parentRel;
}
public void setParentRel(String parentRel) {
this.parentRel = parentRel;
}
public long getLat() {
return lat;
}
public void setLat(long lat) {
this.lat = lat;
}
public long getLng() {
return lng;
}
public void setLng(long lng) {
this.lng = lng;
}
}
package com.mrane.data;
public class Room extends Marker {
public String parentKey;
public String tag;
public Room(String fullName, String shortName, float x, float y,
int groupId, String parentName, String tag, String desc) {
super(fullName, shortName, x, y, groupId, desc);
this.tag = tag;
this.parentKey = parentName;
}
}
package com.mrane.navigation;
import android.animation.ValueAnimator;
import android.annotation.TargetApi;
import android.os.Build;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Interpolator;
import app.insti.R;
import app.insti.fragment.MapFragment;
import com.mrane.navigation.SlidingUpPanelLayout.PanelSlideListener;
public class CardSlideListener implements PanelSlideListener,
ValueAnimator.AnimatorUpdateListener {
private MapFragment mainActivity;
private SlidingUpPanelLayout slidingLayout;
private EndDetectScrollView scrollView;
private ValueAnimator animator;
private static final long TIME_ANIMATION_SHOW = 250;
public CardSlideListener(MapFragment mainActivity) {
this.mainActivity = mainActivity;
slidingLayout = mainActivity.getSlidingLayout();
scrollView = (EndDetectScrollView) mainActivity.getActivity()
.findViewById(R.id.new_expanded_place_card_scroll);
animator = new ValueAnimator();
animator.addUpdateListener(this);
Interpolator i = new Interpolator() {
public float getInterpolation(float t) {
t -= 1.0f;
return t * t * t * t * t + 1.0f;
}
};
animator.setInterpolator(i);
}
@Override
public void onPanelSlide(View panel, float slideOffset) {
// setActionBarTranslation(slidingLayout.getCurrentParalaxOffset());
// if(slideOffset >= slidingLayout.getAnchorPoint()){
// mainActivity.getSupportActionBar().hide();
// }
// else{
// mainActivity.getSupportActionBar().show();
// }
}
@Override
public void onPanelCollapsed(View panel) {
}
@Override
public void onPanelExpanded(View panel) {
scrollView.requestDisallowInterceptTouchEvent(false);
scrollView.setScrollingEnabled(true);
}
@Override
public void onPanelAnchored(View panel) {
scrollView.requestDisallowInterceptTouchEvent(true);
scrollView.setScrollingEnabled(false);
}
@Override
public void onPanelHidden(View panel) {
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void setActionBarTranslation(float y) {
// Figure out the actionbar height
int actionBarHeight = 20;
// A hack to add the translation to the action bar
ViewGroup content = ((ViewGroup) mainActivity.getActivity().findViewById(
android.R.id.content).getParent());
int children = content.getChildCount();
for (int i = 0; i < children; i++) {
View child = content.getChildAt(i);
if (child.getId() != android.R.id.content) {
if (y <= -actionBarHeight) {
child.setVisibility(View.GONE);
} else {
child.setVisibility(View.VISIBLE);
child.setTranslationY(y);
}
}
}
}
public void dismissCard() {
animator.cancel();
int initialPanelHeight = slidingLayout.getPanelHeight();
int finalPanelHeight = 0;
animator.setIntValues(initialPanelHeight, finalPanelHeight);
animator.setDuration(TIME_ANIMATION_SHOW);
animator.start();
}
public void showCard() {
animator.cancel();
int initialPanelHeight = slidingLayout.getPanelHeight();
int finalPanelHeight = mainActivity.getResources()
.getDimensionPixelSize(R.dimen.hidden_card_height);
animator.setIntValues(initialPanelHeight, finalPanelHeight);
animator.setDuration(TIME_ANIMATION_SHOW);
animator.start();
}
@Override
public void onAnimationUpdate(ValueAnimator animator) {
int panelHeight = (Integer) animator.getAnimatedValue();
slidingLayout.setPanelHeight(panelHeight);
}
}
package com.mrane.navigation;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ScrollView;
public class EndDetectScrollView extends ScrollView {
private enum ScrollState {
TOP, BETWEEN, BOTTOM
}
private ScrollState mCurrState = ScrollState.TOP;
private boolean scrollable = true;
public interface ScrollEndListener {
public void onScrollHitBottom();
public void onScrollHitTop();
public void onScrollInBetween();
}
private ScrollEndListener listener;
public EndDetectScrollView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public EndDetectScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
public EndDetectScrollView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
}
public void setScrollEndListener(ScrollEndListener l) {
listener = l;
}
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
View bottomChild = (View) getChildAt(getChildCount() - 1);
int bottomDiff = (bottomChild.getBottom() - (getHeight() + getScrollY() + bottomChild
.getTop()));// Calculate the scrolldiff
if (getScrollY() == 0) { // if scrollY==0 top has been reached
if (listener != null)
listener.onScrollHitTop();
mCurrState = ScrollState.TOP;
} else if (bottomDiff == 0) {
if (listener != null)
listener.onScrollHitBottom();
mCurrState = ScrollState.BOTTOM;
} else {
if (listener != null)
listener.onScrollInBetween();
mCurrState = ScrollState.BETWEEN;
}
super.onScrollChanged(l, t, oldl, oldt);
}
public boolean isAtTop() {
return mCurrState == ScrollState.TOP;
}
public boolean isAtBottom() {
return mCurrState == ScrollState.BOTTOM;
}
public boolean isInBetween() {
return mCurrState == ScrollState.BETWEEN;
}
public void setScrollingEnabled(boolean scrollable) {
this.scrollable = scrollable;
}
public boolean isScrollable() {
return scrollable;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
// if we can scroll pass the event to the superclass
if (scrollable)
return super.onTouchEvent(ev);
// only continue to handle the touch event if scrolling enabled
return scrollable; // scrollable is always false at this point
default:
return super.onTouchEvent(ev);
}
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
// Don't do anything with intercepted touch events if
// we are not scrollable
if (!scrollable)
return false;
else
return super.onInterceptTouchEvent(ev);
}
}
This diff is collapsed.
This diff is collapsed.
/*
Copyright 2014 David Morrissey
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.mrane.zoomview;
import android.graphics.PointF;
import java.io.Serializable;
/**
* Wraps the scale, center and orientation of a displayed image for easy restoration on screen rotate.
*/
public class ImageViewState implements Serializable {
/**
*
*/
private static final long serialVersionUID = -4397017033346987595L;
private float scale;
private float centerX;
private float centerY;
private int orientation;
public ImageViewState(float scale, PointF center, int orientation) {
this.scale = scale;
this.centerX = center.x;
this.centerY = center.y;
this.orientation = orientation;
}
public float getScale() {
return scale;
}
public PointF getCenter() {
return new PointF(centerX, centerY);
}
public int getOrientation() {
return orientation;
}
}
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:startColor="#20000000"
android:endColor="@android:color/transparent"
android:angle="90" >
</gradient>
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:startColor="#20000000"
android:endColor="@android:color/transparent"
android:angle="270" >
</gradient>
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Drop Shadow Stack -->
<!-- Background -->
<item>
<shape>
<solid android:color="#e5e5e5" />
</shape>
</item>
</layer-list>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="#30555555"/>
<corners android:radius="2dp" />
</shape>
</item>
<item
android:left="0dp"
android:right="0dp"
android:top="0dp"
android:bottom="2dp">
<shape android:shape="rectangle">
<solid android:color="#FFFFFF"/>
<corners android:radius="2dp" />
</shape>
</item>
</layer-list>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Drop Shadow Stack -->
<item>
<shape>
<padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
<solid android:color="#00999999" />
</shape>
</item>
<item>
<shape>
<padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
<solid android:color="#10999999" />
</shape>
</item>
<item>
<shape>
<padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
<solid android:color="#20999999" />
</shape>
</item>
<item>
<shape>
<padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
<solid android:color="#10999999" />
</shape>
</item>
<item>
<shape>
<padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
<solid android:color="#00999999" />
</shape>
</item>
<!-- Background -->
<item>
<shape>
<solid android:color="@android:color/transparent" />
</shape>
</item>
</layer-list>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Drop Shadow Stack -->
<!-- <item>
<shape>
<padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
<solid android:color="#00999999" />
<corners android:radius="2dp" />
</shape>
</item>
<item>
<shape>
<padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
<solid android:color="#10999999" />
<corners android:radius="2dp" />
</shape>
</item>
<item>
<shape>
<padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
<solid android:color="#20999999" />
<corners android:radius="2dp" />
</shape>
</item>
<item>
<shape>
<padding android:top="0dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
<solid android:color="#30999999" />
<corners android:radius="2dp" />
</shape>
</item>
<item>
<shape>
<padding android:top="0dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
<solid android:color="#20999999" />
<corners android:radius="2dp" />
</shape>
</item>-->
<!-- Background -->
<item>
<shape>
<solid android:color="#F0FFFFFF" />
<!-- <corners android:radius="2dp" />-->
</shape>
</item>
</layer-list>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Drop Shadow Stack -->
<item>
<shape>
<padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
<solid android:color="#00999999" />
<corners android:radius="5dp" />
</shape>
</item>
<item>
<shape>
<padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
<solid android:color="#00999999" />
<corners android:radius="5dp" />
</shape>
</item>
<item>
<shape>
<padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
<solid android:color="#00999999" />
<corners android:radius="5dp" />
</shape>
</item>
<item>
<shape>
<padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
<solid android:color="#00999999" />
<corners android:radius="5dp" />
</shape>
</item>
<item>
<shape>
<padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
<solid android:color="#00999999" />
<corners android:radius="5dp" />
</shape>
</item>
<!-- Background -->
<item>
<shape>
<gradient
android:type="linear"
android:centerX="6%"
android:startColor="#FFe4e4e4"
android:centerColor="#FFf6f6f6"
android:endColor="#FFffffff"
android:angle="90"/>
<corners android:radius="5dp" />
</shape>
</item>
</layer-list>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
<gradient
android:type="linear"
android:centerX="20%"
android:startColor="#66000000"
android:centerColor="#22000000"
android:endColor="#00f6f6f6"
android:angle="270"/>
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
<gradient
android:type="linear"
android:centerX="2%"
android:startColor="#FFe4e4e4"
android:centerColor="#FFf6f6f6"
android:endColor="#FFffffff"
android:angle="90"/>
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
<gradient
android:type="linear"
android:centerX="60%"
android:startColor="#00000000"
android:centerColor="#19000000"
android:endColor="#FF000000"
android:angle="270"/>
</shape>
\ No newline at end of file
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportHeight="108"
android:viewportWidth="108">
<path
android:fillType="evenOdd"
android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
android:strokeColor="#00000000"
android:strokeWidth="1">
<aapt:attr name="android:fillColor">
<gradient
android:endX="78.5885"
android:endY="90.9159"
android:startX="48.7653"
android:startY="61.0927"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
android:strokeColor="#00000000"
android:strokeWidth="1" />
</vector>
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment