Create view for habit history; other minor changes

pull/30/head
Alinson S. Xavier 11 years ago
parent c41e71003b
commit 11d6bbd6f6

@ -5,9 +5,10 @@
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="14"
android:minSdkVersion="21"
android:targetSdkVersion="22" />
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.VIBRATE" />
<application
android:name="com.activeandroid.app.Application"
@ -23,9 +24,9 @@
android:value="6" />
<activity
android:name="org.isoron.uhabits.MainActivity"
android:name=".MainActivity"
android:label="@string/app_name"
android:launchMode="singleInstance">
android:launchMode="singleInstance" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
@ -33,12 +34,17 @@
</intent-filter>
</activity>
<receiver android:name="ReminderAlarmReceiver">
</receiver>
<receiver android:name="ReminderAlarmDismissReceiver">
</receiver>
<receiver android:name=".ReminderAlarmReceiver" >
</receiver>
<activity
android:name=".ShowHabitActivity"
android:label="@string/title_activity_show_habit"
android:parentActivityName=".MainActivity" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="org.isoron.uhabits.MainActivity" />
</activity>
</application>
</manifest>

@ -5,19 +5,11 @@
android:layout_height="match_parent"
android:background="#ffffff" >
<!-- <ListView -->
<!-- android:id="@+id/listView" -->
<!-- android:layout_width="match_parent" -->
<!-- android:layout_height="match_parent" -->
<!-- android:divider="#00000000" -->
<!-- android:dividerHeight="0dp"> -->
<!-- </ListView> -->
<com.mobeta.android.dslv.DragSortListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="#10000000"
android:divider="@color/windowBackground"
android:dividerHeight="1dp"
dslv:drag_enabled="true"
dslv:drag_handle_id="@drawable/habits_header_check"
@ -25,21 +17,23 @@
dslv:float_alpha="0.5"
dslv:sort_enabled="true"
dslv:track_drag_sort="false"
dslv:use_default_controller="true" />
dslv:use_default_controller="true"
android:paddingTop="42dp"
android:background="@color/windowBackground"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:background="#f0f0f0"
android:elevation="2dp"
android:background="#ffffff"
android:paddingRight="4dp"
>
android:paddingRight="4dp" >
<TextView
android:id="@+id/tvStarHeader"
android:layout_width="36dp"
android:layout_height="match_parent"
android:layout_height="42dp"
android:layout_marginTop="0dp"
android:gravity="center"
android:paddingTop="1dp" />
@ -47,13 +41,14 @@
<TextView
android:id="@+id/tvNameHeader"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_height="42dp"
android:layout_weight="1"
android:gravity="center_vertical"
android:paddingBottom="6dp"
android:paddingLeft="0dp"
android:paddingRight="6dp"
android:paddingTop="6dp" />
android:paddingTop="6dp"
android:text="" />
<LinearLayout
android:id="@+id/llButtonsHeader"

@ -1,19 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/llOuter"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#10000000"
android:background="@color/windowBackground"
android:baselineAligned="false"
android:clipToPadding="false"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingTop="0dp"
android:paddingBottom="4dp"
android:paddingLeft="4dp"
android:paddingRight="4dp"
android:paddingLeft="6dp"
android:paddingRight="6dp"
>
<LinearLayout
android:id="@+id/llInner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/ripple_background"

@ -8,7 +8,7 @@
<fragment
android:id="@+id/fragment1"
android:name="org.isoron.uhabits.dialogs.ShowHabitsFragment"
android:name="org.isoron.uhabits.dialogs.ListHabitsFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />

@ -0,0 +1,125 @@
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:fillViewport="true" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/windowBackground"
android:orientation="vertical"
android:paddingBottom="4dp"
android:paddingLeft="4dp"
android:paddingRight="4dp"
android:paddingTop="0dp"
android:transitionName="mainWindow"
tools:context="org.isoron.uhabits.ShowHabitActivity" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:background="@color/white"
android:elevation="2dp"
android:orientation="vertical"
android:padding="16dp" >
<TextView
android:id="@+id/tvOverview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:text="Overview"
android:textSize="16sp"
android:textStyle="bold" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="4dp"
android:layout_marginTop="4dp" >
<TextView
android:layout_width="120dp"
android:layout_height="wrap_content"
android:text="Habit strength" >
</TextView>
<TextView
android:id="@+id/tvStrength"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="" >
</TextView>
</LinearLayout>
<!--
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="4dp"
android:layout_marginTop="4dp" >
<TextView
android:layout_width="120dp"
android:layout_height="wrap_content"
android:text="Current streak" >
</TextView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="12 days\nJun 11, 2015 — Jun 23, 2015" >
</TextView>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="4dp"
android:layout_marginTop="4dp" >
<TextView
android:layout_width="120dp"
android:layout_height="wrap_content"
android:text="Best streak" >
</TextView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="30 days\nMar 12, 2015 — Apr 12, 2015" >
</TextView>
</LinearLayout>
-->
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:elevation="2dp"
android:orientation="vertical"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:paddingLeft="16dp"
android:paddingRight="4dp"
>
<TextView
android:id="@+id/tvHistory"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:text="History"
android:textSize="16sp"
android:textStyle="bold" />
<LinearLayout
android:id="@+id/llHistory"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" />
</LinearLayout>
</LinearLayout>
</ScrollView>

@ -0,0 +1,15 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="org.isoron.uhabits.ShowHabitActivity"
tools:ignore="MergeRootFrame" >
<fragment
android:id="@+id/fragment2"
android:name="org.isoron.uhabits.dialogs.ShowHabitFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>

@ -0,0 +1,11 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context="org.isoron.uhabits.ShowHabitActivity" >
<item
android:id="@+id/action_settings"
android:orderInCategory="100"
android:showAsAction="never"
android:title="@string/action_settings"/>
</menu>

@ -1,11 +1,14 @@
<resources>
<style name="AppBaseTheme" parent="android:Theme.Material">
<item name="android:textColor">#606060</item>
<item name="android:colorPrimary">@color/primary</item>
<item name="android:colorPrimaryDark">@color/primary_darker</item>
<item name="android:dialogTheme">@style/MyDialogStyle</item>
<item name="android:alertDialogTheme">@style/MyDialogStyle</item>
<item name="android:windowContentTransitions">true</item>
<item name="android:windowAllowEnterTransitionOverlap">true</item>
<item name="android:windowAllowReturnTransitionOverlap">true</item>
</style>
<style name="MyDialogStyle" parent="android:Theme.Material.Light.Dialog">

@ -19,17 +19,18 @@
<color name="primary">#00517b</color>
<color name="primary_darker">#003d5d</color>
<color name="accent">#9a4000</color>
<color name="windowBackground">#e6e6e6</color>
<color name="white">#ffffff</color>
<color name="grey">#cccccc</color>
<!-- Time and Date picker -->
<color name="circle_background">#f2f2f2</color>
<color name="line_background">#cccccc</color>
<color name="ampm_text_color">#8c8c8c</color>
<color name="done_text_color_normal">#000000</color>
<color name="done_text_color_disabled">#cccccc</color>
<color name="numbers_text_color">#8c8c8c</color>
<color name="transparent">#00000000</color>
<color name="transparent_black">#7f000000</color>
<color name="blue">#33b5e5</color>
@ -37,11 +38,9 @@
<color name="neutral_pressed">#33999999</color>
<color name="darker_blue">#0099cc</color>
<color name="date_picker_text_normal">#ff999999</color>
<color name="calendar_header">#999999</color>
<color name="date_picker_view_animator">#f2f2f2</color>
<color name="calendar_selected_date_text">#ffd1d2d4</color>
<color name="done_text_color">#888888</color>
<color name="done_text_color_dark">#888888</color>

@ -1,17 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name">μHabits</string>
<string name="action_settings">Settings</string>
<string name="edit">Edit</string>
<string name="delete">Delete</string>
<string name="add_habit">Add habit</string>
<string name="color_picker_default_title">Select a Color</string>
<string name="color_swatch_description">Color <xliff:g id="color_index" example="14">%1$d</xliff:g></string>
<string name="color_swatch_description_selected">Color <xliff:g id="color_index" example="14">%1$d</xliff:g> selected</string>
<string name="toast_habit_created">Habit created.</string>
<string name="toast_habit_deleted">Habit deleted.</string>
<string name="toast_nothing_to_undo">Nothing to undo.</string>
@ -38,10 +35,12 @@
<string name="radial_numbers_typeface">sans-serif</string>
<string name="sans_serif">sans-serif</string>
<string name="day_of_week_label_typeface">sans-serif</string>
<string name="habit_key"></string>
<string name="offset_key"></string>
<item type="id" name="KEY_TIMESTAMP"/>
<item name="KEY_TIMESTAMP" type="id"/>
<string name="title_activity_show_habit">ShowHabitActivity</string>
<string name="hello_world">Hello world!</string>
</resources>

@ -0,0 +1,25 @@
package org.isoron.helpers;
public class ColorHelper
{
public static int mixColors(int color1, int color2, float amount)
{
final byte ALPHA_CHANNEL = 24;
final byte RED_CHANNEL = 16;
final byte GREEN_CHANNEL = 8;
final byte BLUE_CHANNEL = 0;
final float inverseAmount = 1.0f - amount;
int a = ((int) (((float) (color1 >> ALPHA_CHANNEL & 0xff) * amount) +
((float) (color2 >> ALPHA_CHANNEL & 0xff) * inverseAmount))) & 0xff;
int r = ((int) (((float) (color1 >> RED_CHANNEL & 0xff) * amount) +
((float) (color2 >> RED_CHANNEL & 0xff) * inverseAmount))) & 0xff;
int g = ((int) (((float) (color1 >> GREEN_CHANNEL & 0xff) * amount) +
((float) (color2 >> GREEN_CHANNEL & 0xff) * inverseAmount))) & 0xff;
int b = ((int) (((float) (color1 & 0xff) * amount) +
((float) (color2 & 0xff) * inverseAmount))) & 0xff;
return a << ALPHA_CHANNEL | r << RED_CHANNEL | g << GREEN_CHANNEL | b << BLUE_CHANNEL;
}
}

@ -6,7 +6,7 @@ import java.util.Date;
import java.util.LinkedList;
import org.isoron.helpers.Command;
import org.isoron.uhabits.dialogs.ShowHabitsFragment;
import org.isoron.uhabits.dialogs.ListHabitsFragment;
import org.isoron.uhabits.models.Habit;
import android.app.Activity;
@ -26,7 +26,7 @@ import android.widget.Toast;
public class MainActivity extends Activity
{
private ShowHabitsFragment showHabitsFragment;
private ListHabitsFragment listHabitsFragment;
private LinkedList<Command> undoList;
private LinkedList<Command> redoList;
@ -45,7 +45,8 @@ public class MainActivity extends Activity
getActionBar().setElevation(5);
setContentView(R.layout.main_activity);
showHabitsFragment = (ShowHabitsFragment) getFragmentManager().findFragmentById(
listHabitsFragment = (ListHabitsFragment) getFragmentManager().findFragmentById(
R.id.fragment1);
Log.d("MainActivity", "Creating activity");
@ -60,7 +61,7 @@ public class MainActivity extends Activity
protected void onStart()
{
super.onStart();
showHabitsFragment.notifyDataSetChanged();
listHabitsFragment.notifyDataSetChanged();
Log.d("MainActivity", "Starting activity");
}
@ -151,7 +152,7 @@ public class MainActivity extends Activity
showToast(command.getExecuteStringId());
if(datasetChanged)
{
showHabitsFragment.notifyDataSetChanged();
listHabitsFragment.notifyDataSetChanged();
}
}
@ -168,7 +169,7 @@ public class MainActivity extends Activity
last.undo();
showToast(last.getUndoStringId());
showHabitsFragment.notifyDataSetChanged();
listHabitsFragment.notifyDataSetChanged();
}
public void redo()

@ -1,30 +0,0 @@
package org.isoron.uhabits;
import org.isoron.uhabits.models.Habit;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.util.Log;
public class ReminderAlarmDismissReceiver extends BroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent)
{
createNotification(context, intent.getData(), intent.getDataString());
}
private void createNotification(Context context, Uri data, String text)
{
for(Habit h : Habit.getHighlightedHabits())
{
Log.d("Alarm", String.format("Removing highlight from: %s", h.name));
h.highlight = 0;
h.save();
}
}
}

@ -0,0 +1,54 @@
package org.isoron.uhabits;
import org.isoron.uhabits.dialogs.ListHabitsFragment;
import org.isoron.uhabits.dialogs.ShowHabitFragment;
import org.isoron.uhabits.models.Habit;
import android.app.Activity;
import android.content.ContentUris;
import android.graphics.drawable.ColorDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
public class ShowHabitActivity extends Activity
{
public Habit habit;
private ShowHabitFragment showHabitFragment;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
getActionBar().setElevation(5);
Uri data = getIntent().getData();
habit = Habit.get(ContentUris.parseId(data));
getActionBar().setTitle(habit.name);
getActionBar().setBackgroundDrawable(new ColorDrawable(habit.color));
setContentView(R.layout.show_habit_activity);
showHabitFragment = (ShowHabitFragment) getFragmentManager().findFragmentById(
R.id.fragment2);
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.show_habit, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
int id = item.getItemId();
if(id == R.id.action_settings)
{
return true;
}
return super.onOptionsItemSelected(item);
}
}

@ -1,5 +1,6 @@
package org.isoron.uhabits.dialogs;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.TimeZone;
@ -9,17 +10,22 @@ import org.isoron.helpers.DateHelper;
import org.isoron.helpers.DialogHelper.OnSavedListener;
import org.isoron.uhabits.MainActivity;
import org.isoron.uhabits.R;
import org.isoron.uhabits.ShowHabitActivity;
import org.isoron.uhabits.models.Habit;
import android.app.Fragment;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.Outline;
import android.graphics.Point;
import android.graphics.Typeface;
import android.net.Uri;
import android.os.Bundle;
import android.os.Vibrator;
import android.text.format.Time;
import android.transition.Explode;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Display;
@ -28,9 +34,9 @@ import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
import android.view.ViewOutlineProvider;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
@ -45,21 +51,22 @@ import com.mobeta.android.dslv.DragSortController;
import com.mobeta.android.dslv.DragSortListView;
import com.mobeta.android.dslv.DragSortListView.DropListener;
public class ShowHabitsFragment extends Fragment implements OnSavedListener, OnItemClickListener,
OnLongClickListener, DropListener
public class ListHabitsFragment extends Fragment implements OnSavedListener, OnItemClickListener,
OnLongClickListener, DropListener, OnClickListener
{
private int tvNameWidth;
private int button_count;
ShowHabitsAdapter adapter;
ListHabitsAdapter adapter;
DragSortListView listView;
MainActivity mainActivity;
TextView tvNameHeader;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Adapter *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
class ShowHabitsAdapter extends BaseAdapter
class ListHabitsAdapter extends BaseAdapter
{
private Context context;
@ -70,7 +77,7 @@ public class ShowHabitsFragment extends Fragment implements OnSavedListener, OnI
"go to school",
"cook dinner & lunch" };
public ShowHabitsAdapter(Context context)
public ListHabitsAdapter(Context context)
{
this.context = context;
@ -81,22 +88,18 @@ public class ShowHabitsFragment extends Fragment implements OnSavedListener, OnI
@Override
public int getCount()
{
return Habit.getCount() + 1;
return Habit.getCount();
}
@Override
public Object getItem(int position)
{
if(position == 0)
return null;
return Habit.getByPosition(position - 1);
return Habit.getByPosition(position);
}
@Override
public long getItemId(int position)
{
if(position == 0)
return 0;
return ((Habit) getItem(position)).getId();
}
@ -107,7 +110,7 @@ public class ShowHabitsFragment extends Fragment implements OnSavedListener, OnI
if(view == null || (Long) view.getTag(R.id.KEY_TIMESTAMP) != DateHelper.getStartOfToday())
{
view = inflater.inflate(R.layout.show_habits_item, null);
view = inflater.inflate(R.layout.list_habits_item, null);
((TextView) view.findViewById(R.id.tvStar)).setTypeface(fontawesome);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(tvNameWidth,
@ -121,47 +124,54 @@ public class ShowHabitsFragment extends Fragment implements OnSavedListener, OnI
LinearLayout.LayoutParams llp = new LinearLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
llp.setMargins(10, 5, 10, 5);
llp.setMargins(2, 0, 2, 0);
for (int i = 0; i < button_count; i++)
{
View check = inflater.inflate(R.layout.show_habits_item_check, null);
View check = inflater.inflate(R.layout.list_habits_item_check, null);
TextView btCheck = (TextView) check.findViewById(R.id.tvCheck);
btCheck.setTypeface(fontawesome);
btCheck.setOnLongClickListener(ShowHabitsFragment.this);
btCheck.setOnLongClickListener(ListHabitsFragment.this);
// btCheck.setLayoutParams(llp);
((LinearLayout) view.findViewById(R.id.llButtons)).addView(check);
}
// LinearLayout llInner = (LinearLayout) view.findViewById(R.id.llInner);
// llInner.setOnClickListener(ListHabitsFragment.this);
view.setTag(R.id.KEY_TIMESTAMP, DateHelper.getStartOfToday());
}
TextView tvStar = (TextView) view.findViewById(R.id.tvStar);
TextView tvName = (TextView) view.findViewById(R.id.tvName);
if(habit == null)
{
tvName.setText(null);
return view;
}
LinearLayout llInner = (LinearLayout) view.findViewById(R.id.llInner);
llInner.setTag(R.string.habit_key, habit.getId());
int inactiveColor = Color.rgb(230, 230, 230);
int inactiveBackgroundColor = Color.WHITE;
int activeColor = habit.color;
tvName.setText(habit.name);
tvName.setTextColor(activeColor);
int score = habit.getScore();
if(score < 5999000)
if(score < Habit.HALF_STAR_CUTOFF)
{
tvStar.setText(context.getString(R.string.fa_star_o));
tvStar.setTextColor(Color.LTGRAY);
tvStar.setTextColor(inactiveColor);
}
else if(score < 12973000)
else if(score < Habit.FULL_STAR_CUTOFF)
{
tvStar.setText(context.getString(R.string.fa_star_half_o));
tvStar.setTextColor(Color.LTGRAY);
tvStar.setTextColor(inactiveColor);
}
else
{
@ -216,14 +226,17 @@ public class ShowHabitsFragment extends Fragment implements OnSavedListener, OnI
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.show_habits, container, false);
View view = inflater.inflate(R.layout.list_habits, container, false);
DisplayMetrics dm = getResources().getDisplayMetrics();
int width = (int) (dm.widthPixels / dm.density);
button_count = (int) ((width - 160) / 42);
tvNameWidth = (int) ((width - 30 - button_count * 42) * dm.density);
adapter = new ShowHabitsAdapter(getActivity());
tvNameHeader = (TextView) view.findViewById(R.id.tvNameHeader);
// updateStarCount();
adapter = new ListHabitsAdapter(getActivity());
listView = (DragSortListView) view.findViewById(R.id.listView);
listView.setAdapter(adapter);
listView.setOnItemClickListener(this);
@ -245,7 +258,7 @@ public class ShowHabitsFragment extends Fragment implements OnSavedListener, OnI
for (int i = 0; i < button_count; i++)
{
View check = inflater.inflate(R.layout.show_habits_header_check, null);
View check = inflater.inflate(R.layout.list_habits_header_check, null);
Button btCheck = (Button) check.findViewById(R.id.tvCheck);
btCheck.setText(day.getDisplayName(GregorianCalendar.DAY_OF_WEEK,
GregorianCalendar.SHORT, Locale.US) + "\n"
@ -313,9 +326,21 @@ public class ShowHabitsFragment extends Fragment implements OnSavedListener, OnI
return super.onContextItemSelected(menuItem);
}
long lastLongClick = 0;
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3)
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
if(new Date().getTime() - lastLongClick < 1000) return;
Habit habit = Habit.getByPosition(position);
Log.d("ItemClick", Long.toString(id));
Intent intent = new Intent(getActivity(), ShowHabitActivity.class);
intent.setData(Uri.parse("content://org.isoron.uhabits/habit/"
+ habit.getId()));
getActivity().getWindow().setExitTransition(new Explode());
startActivity(intent);
}
@Override
@ -337,6 +362,7 @@ public class ShowHabitsFragment extends Fragment implements OnSavedListener, OnI
if(id == R.id.tvCheck)
{
lastLongClick = new Date().getTime();
Habit habit = Habit.get((Long) v.getTag(R.string.habit_key));
int offset = (Integer) v.getTag(R.string.offset_key);
long timestamp = DateHelper.getStartOfDay(DateHelper.getLocalTime() - offset
@ -347,7 +373,6 @@ public class ShowHabitsFragment extends Fragment implements OnSavedListener, OnI
Vibrator vb = (Vibrator) getActivity().getSystemService(Context.VIBRATOR_SERVICE);
vb.vibrate(100);
adapter.notifyDataSetChanged();
return true;
}
@ -357,13 +382,32 @@ public class ShowHabitsFragment extends Fragment implements OnSavedListener, OnI
private void executeCommand(Command c)
{
mainActivity.executeCommand(c, false);
adapter.notifyDataSetChanged();
notifyDataSetChanged();
}
@Override
public void drop(int from, int to)
{
Habit.reorder(from - 1, to - 1);
adapter.notifyDataSetChanged();
Habit.reorder(from, to);
notifyDataSetChanged();
}
@Override
public void onClick(View v)
{
}
void updateStarCount()
{
Log.d("StarCount", "updating star count");
String msg = "";
int starCount = Habit.getStarCount();
if(starCount == 1)
msg = String.format("%d star", starCount);
else if(starCount > 1)
msg = String.format("%d stars", starCount);
tvNameHeader.setText(msg);
}
}

@ -0,0 +1,66 @@
package org.isoron.uhabits.dialogs;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;
import org.isoron.helpers.ColorHelper;
import org.isoron.helpers.DateHelper;
import org.isoron.uhabits.R;
import org.isoron.uhabits.ShowHabitActivity;
import org.isoron.uhabits.models.Habit;
import org.isoron.uhabits.views.HabitHistoryView;
import android.app.Fragment;
import android.graphics.Color;
import android.graphics.Typeface;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.TextView;
public class ShowHabitFragment extends Fragment
{
protected ShowHabitActivity activity;
private Habit habit;
@Override
public void onStart()
{
super.onStart();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
Log.d("ShowHabitActivity", "Creating view...");
View view = inflater.inflate(R.layout.show_habit, container, false);
activity = (ShowHabitActivity) getActivity();
habit = activity.habit;
int darkerHabitColor = ColorHelper.mixColors(habit.color, Color.BLACK, 0.75f);
activity.getWindow().setStatusBarColor(darkerHabitColor);
TextView tvHistory = (TextView) view.findViewById(R.id.tvHistory);
TextView tvOverview = (TextView) view.findViewById(R.id.tvOverview);
tvHistory.setTextColor(habit.color);
tvOverview.setTextColor(habit.color);
TextView tvStrength = (TextView) view.findViewById(R.id.tvStrength);
tvStrength.setText(String.format("%.2f%%", ((float) habit.getScore() / Habit.MAX_SCORE) * 100));
LinearLayout llHistory = (LinearLayout) view.findViewById(R.id.llHistory);
HabitHistoryView hhv = new HabitHistoryView(activity, habit, 40);
llHistory.addView(hhv);
return view;
}
}

@ -8,6 +8,7 @@ import org.isoron.uhabits.R;
import android.annotation.SuppressLint;
import android.graphics.Color;
import android.util.Log;
import com.activeandroid.Model;
import com.activeandroid.annotation.Column;
@ -34,6 +35,10 @@ public class Habit extends Model
Color.parseColor("#872086"), Color.parseColor("#c31764"),
Color.parseColor("#000000"), Color.parseColor("#aaaaaa") };
public static final int HALF_STAR_CUTOFF = 5999000;
public static final int FULL_STAR_CUTOFF = 12973000;
public static final int MAX_SCORE = 19259500;
@Column(name = "name")
public String name;
@ -197,12 +202,14 @@ public class Habit extends Model
this.position = model.position;
this.reminder_hour = model.reminder_hour;
this.reminder_min = model.reminder_min;
this.highlight = model.highlight;
}
public Habit()
{
this.color = colors[11];
this.position = Habit.getCount();
this.highlight = 0;
}
public static Habit get(Long id)
@ -425,6 +432,7 @@ public class Habit extends Model
return lastScore;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Ordering *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
@ -468,4 +476,18 @@ public class Habit extends Model
r.save();
}
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Statistics *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
public static int getStarCount()
{
String args[] = {};
return SQLiteUtils.intQuery(
"select count(*) from (select score, max(timestamp) from " +
"score group by habit) as scores where scores.score >= "
+ Integer.toString(12973000), args);
}
}

@ -0,0 +1,236 @@
package org.isoron.uhabits.views;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;
import org.isoron.helpers.ColorHelper;
import org.isoron.helpers.DateHelper;
import org.isoron.uhabits.R;
import org.isoron.uhabits.models.Habit;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.support.v4.view.MotionEventCompat;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
public class HabitHistoryView extends View
{
private Habit habit;
private int reps[];
private Context context;
private Paint pSquareBg, pSquareFg, pTextHeader;
private int width, height;
private int squareSize, squareSpacing;
private int nColumns, offsetWeeks;
private int colorPrimary, colorPrimaryBrighter, grey;
public HabitHistoryView(Context context, Habit habit, int squareSize)
{
super(context);
this.habit = habit;
this.context = context;
this.squareSize = squareSize;
Typeface fontawesome = Typeface.createFromAsset(context.getAssets(),
"fontawesome-webfont.ttf");
colorPrimary = habit.color;
colorPrimaryBrighter = ColorHelper.mixColors(colorPrimary, Color.WHITE, 0.5f);
grey = Color.rgb(230, 230, 230);
squareSpacing = 2;
pTextHeader = new Paint();
pTextHeader.setColor(Color.LTGRAY);
pTextHeader.setTextAlign(Align.LEFT);
pTextHeader.setTextSize(squareSize * 0.5f);
pTextHeader.setAntiAlias(true);
pSquareBg = new Paint();
pSquareBg.setColor(habit.color);
pSquareFg = new Paint();
pSquareFg.setColor(Color.WHITE);
pSquareFg.setAntiAlias(true);
// pSquareFg.setTypeface(fontawesome);
pSquareFg.setTextSize(squareSize * 0.5f);
pSquareFg.setTextAlign(Align.CENTER);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(getMeasuredWidth(), 8 * squareSize);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh)
{
width = w;
height = h;
nColumns = (w / squareSize) - 1;
fetchReps();
}
private void fetchReps()
{
Calendar currentDate = new GregorianCalendar();
currentDate.add(Calendar.DAY_OF_YEAR, -offsetWeeks * 7);
int dayOfWeek = currentDate.get(Calendar.DAY_OF_WEEK) % 7;
long dateTo = DateHelper.getStartOfToday();
for (int i = 0; i < 7 - dayOfWeek; i++)
dateTo += DateHelper.millisecondsInOneDay;
for (int i = 0; i < offsetWeeks * 7; i++)
dateTo -= DateHelper.millisecondsInOneDay;
long dateFrom = dateTo;
for (int i = 0; i < nColumns * 7; i++)
dateFrom -= DateHelper.millisecondsInOneDay;
reps = habit.getReps(dateFrom, dateTo);
}
@Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
Rect square = new Rect(0, 0, squareSize - squareSpacing, squareSize - squareSpacing);
Calendar currentDate = new GregorianCalendar();
currentDate.add(Calendar.DAY_OF_YEAR, -(offsetWeeks-1) * 7);
int nDays = nColumns * 7;
int todayWeekday = new GregorianCalendar().get(Calendar.DAY_OF_WEEK) % 7;
currentDate.add(Calendar.DAY_OF_YEAR, -nDays);
SimpleDateFormat dfMonth = new SimpleDateFormat("MMM");
SimpleDateFormat dfYear = new SimpleDateFormat("yyyy");
String previousMonth = "";
String previousYear = "";
int colors[] = { grey, colorPrimaryBrighter, colorPrimary };
String markers[] = { context.getString(R.string.fa_times),
context.getString(R.string.fa_check), context.getString(R.string.fa_check) };
float squareTextOffset = pSquareFg.getFontSpacing() * 0.4f;
float headerTextOffset = pTextHeader.getFontSpacing() * 0.3f;
boolean justPrintedYear = false;
int k = nDays;
for (int i = 0; i < nColumns; i++)
{
String month = dfMonth.format(currentDate.getTime());
String year = dfYear.format(currentDate.getTime());
if(!month.equals(previousMonth))
{
int offset = 0;
if(justPrintedYear)
offset += squareSize;
canvas.drawText(month, square.left + offset, square.bottom - headerTextOffset,
pTextHeader);
previousMonth = month;
justPrintedYear = false;
}
else if(!year.equals(previousYear))
{
canvas.drawText(year, square.left, square.bottom - headerTextOffset, pTextHeader);
previousYear = year;
justPrintedYear = true;
}
else
{
justPrintedYear = false;
}
square.offset(0, squareSize);
for (int j = 0; j < 7; j++)
{
if(!(i == nColumns - 1 && offsetWeeks == 0 && j > todayWeekday))
{
pSquareBg.setColor(colors[reps[k]]);
canvas.drawRect(square, pSquareBg);
// canvas.drawText(markers[reps[k]], square.centerX(), square.centerY()
// + squareTextOffset, pSquareFg);
canvas.drawText(Integer.toString(currentDate.get(Calendar.DAY_OF_MONTH)),
square.centerX(), square.centerY() + squareTextOffset, pSquareFg);
}
currentDate.add(Calendar.DAY_OF_MONTH, 1);
square.offset(0, squareSize);
k--;
}
square.offset(squareSize, -8 * squareSize);
}
String wdays[] = { "Sat", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri" };
for (int i = 0; i < 7; i++)
{
square.offset(0, squareSize);
canvas.drawText(wdays[i], square.left + headerTextOffset, square.bottom
- headerTextOffset, pTextHeader);
}
}
private Float prevX, prevY;
@Override
public boolean onTouchEvent(MotionEvent event)
{
int action = event.getAction();
int pointerIndex = MotionEventCompat.getActionIndex(event);
final float x = MotionEventCompat.getX(event, pointerIndex);
final float y = MotionEventCompat.getY(event, pointerIndex);
if(action == MotionEvent.ACTION_DOWN)
{
prevX = x;
prevY = y;
}
if(action == MotionEvent.ACTION_MOVE)
{
float dx = x - prevX;
float dy = y - prevY;
int newOffsetWeeks = offsetWeeks + (int) (dx / squareSize);
newOffsetWeeks = Math.max(0, newOffsetWeeks);
if(newOffsetWeeks != offsetWeeks)
{
prevX = x;
prevY = y;
offsetWeeks = newOffsetWeeks;
fetchReps();
invalidate();
}
}
return true;
}
}
Loading…
Cancel
Save