it.tidalwave.bluebill.mobile.android.observation.AndroidCountAndGenderView Maven / Gradle / Ivy
The newest version!
/***********************************************************************************************************************
*
* blueBill Mobile - Android - open source birding
* Copyright (C) 2009-2011 by Tidalwave s.a.s. (http://www.tidalwave.it)
*
***********************************************************************************************************************
*
* 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.
*
***********************************************************************************************************************
*
* WWW: http://bluebill.tidalwave.it/mobile
* SCM: https://java.net/hg/bluebill-mobile~android-src
*
**********************************************************************************************************************/
package it.tidalwave.bluebill.mobile.android.observation;
import javax.annotation.Nonnull;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Arrays;
import java.util.List;
import it.tidalwave.bluebill.taxonomy.mobile.Taxon;
import it.tidalwave.bluebill.mobile.observation.ui.CountAndGenderFormModel;
import it.tidalwave.bluebill.mobile.observation.ui.CountAndGenderFormModel.CountType;
import it.tidalwave.bluebill.mobile.observation.ui.CountAndGenderView;
import it.tidalwave.bluebill.mobile.observation.ui.CountAndGenderViewController;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import android.widget.Spinner;
import android.widget.TextView;
import it.tidalwave.bluebill.mobile.android.R;
import lombok.extern.slf4j.Slf4j;
import static it.tidalwave.bluebill.mobile.observation.ui.CountAndGenderFormModel.CountType.*;
import static it.tidalwave.ui.android.view.AndroidBindings.*;
import static it.tidalwave.role.ui.android.TextViewRenderable.TextViewRenderable;
/***********************************************************************************************************************
*
* @stereotype View
*
* @author Fabrizio Giudici
* @version $Id$
*
**********************************************************************************************************************/
@Slf4j
public class AndroidCountAndGenderView extends LinearLayout implements CountAndGenderView
{
private TextView tvTaxon;
private Button btOk;
private Button btAddMore;
private Button btAddNote;
private RadioButton rbNotCounted;
private RadioButton rbSimpleCardinality;
private RadioButton rbApproxCardinality;
private RadioButton rbRangeCardinality;
private EditText etSimpleCardinality;
private EditText etApproxCardinality;
private EditText etRangeCardinalityLower;
private EditText etRangeCardinalityUpper;
private Spinner spGender;
private CheckBox cbWatched;
private CheckBox cbListened;
private final AndroidTextNoteController textNoteController = new AndroidTextNoteController(this.getContext());
/*******************************************************************************************************************
*
*
******************************************************************************************************************/
private final PropertyChangeListener focusRequestor = new PropertyChangeListener()
{
public void propertyChange (final @Nonnull PropertyChangeEvent event)
{
final CountType countType = (CountType)event.getNewValue();
// FIXME: this wouldn't be neeed if we didn't have multiple input components for the value
etSimpleCardinality.setFocusableInTouchMode(countType == EXACT);
etApproxCardinality.setFocusableInTouchMode(countType == APPROXIMATED);
etRangeCardinalityLower.setFocusableInTouchMode(countType == RANGE);
// END FIXME
switch (countType)
{
case NOT_COUNTED:
// FIXME: remove the focus from etComponents
break;
case EXACT:
etSimpleCardinality.requestFocus();
break;
case APPROXIMATED:
etApproxCardinality.requestFocus();
break;
case RANGE:
etRangeCardinalityLower.requestFocus();
break;
}
}
};
/*******************************************************************************************************************
*
* The fact that we open a pop up for entering the note is a decision of this View, so shouldn't be handled by the
* Controller.
*
******************************************************************************************************************/
private final OnClickListener btAddNoteClickListener = new OnClickListener()
{
public void onClick (final @Nonnull View view)
{
textNoteController.editNote();
}
};
/*******************************************************************************************************************
*
*
******************************************************************************************************************/
public AndroidCountAndGenderView (final @Nonnull Context context)
{
super(context);
}
/*******************************************************************************************************************
*
*
******************************************************************************************************************/
public AndroidCountAndGenderView (final @Nonnull Context context, final @Nonnull AttributeSet attrs)
{
super(context, attrs);
}
/*******************************************************************************************************************
*
*
******************************************************************************************************************/
public void initialize (final @Nonnull CountAndGenderViewController controller)
{
log.info("initialize({})", controller);
tvTaxon = (TextView)findViewById(R.id.tvTaxon);
btOk = (Button)findViewById(R.id.btOk);
btAddMore = (Button)findViewById(R.id.btAddMore);
btAddNote = (Button)findViewById(R.id.btAddNote);
rbNotCounted = (RadioButton)findViewById(R.id.rbNotCounted);
rbSimpleCardinality = (RadioButton)findViewById(R.id.rbSimpleCardinality);
rbApproxCardinality = (RadioButton)findViewById(R.id.rbApproxCardinality);
rbRangeCardinality = (RadioButton)findViewById(R.id.rbRangeCardinality);
etSimpleCardinality = (EditText)findViewById(R.id.etSimpleCardinality);
etApproxCardinality = (EditText)findViewById(R.id.etApproxCardinality);
etRangeCardinalityLower = (EditText)findViewById(R.id.etRangeCardinalityLower);
etRangeCardinalityUpper = (EditText)findViewById(R.id.etRangeCardinalityUpper);
spGender = (Spinner)findViewById(R.id.spGender);
cbWatched = (CheckBox)findViewById(R.id.cbSeen); // FIXME rename R.id. following the field
cbListened = (CheckBox)findViewById(R.id.cbHeard); // FIXME rename R.id. following the field
bind(btOk, controller.getOkAction());
bind(btAddMore, controller.getAddMoreAction());
btAddNote.setOnClickListener(btAddNoteClickListener);
}
/*******************************************************************************************************************
*
* {@inheritDoc}
*
******************************************************************************************************************/
public void bindModel (final @Nonnull CountAndGenderFormModel model)
{
log.info("bindModel({})", model);
// FIXME: run in UI Thread but also wait for completion
bind(etSimpleCardinality, model.getCount());
bind(etApproxCardinality, model.getCount());
bind(etRangeCardinalityLower, model.getCount());
bind(etRangeCardinalityUpper, model.getMaxCount());
bind(cbWatched, model.getWatched());
bind(cbListened, model.getListened());
bind(spGender, model.getGender());
// FIXME: this assumes that the radiobuttons are enumerated in the same order as the enum values
// Would be easier to bind(radioButton, property, specificValue)
final List radioButtons = Arrays.asList
(
rbNotCounted,
rbSimpleCardinality,
rbApproxCardinality,
rbRangeCardinality
);
bind(radioButtons, model.getCountType());
// END FIXME
textNoteController.bind(model.getNote());
model.getCountType().addPropertyChangeListener(focusRequestor);
}
/*******************************************************************************************************************
*
* {@inheritDoc}
*
******************************************************************************************************************/
public void renderTaxon (final @Nonnull Taxon taxon)
{
post(new Runnable()
{
@Override
public void run()
{
log.info("renderTaxon({})", taxon);
taxon.as(TextViewRenderable).renderTo(tvTaxon);
}
});
}
}