mirror of
https://github.com/moparisthebest/Yaaic
synced 2025-01-08 12:18:07 -05:00
Replace gallery view for conversations by ViewPager. Fixes #38.
This commit is contained in:
parent
659d6c0b89
commit
e04499070a
@ -38,7 +38,7 @@ along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
android:src="@drawable/disconnected"/>
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="3dp"
|
||||
android:textSize="12sp"
|
||||
@ -46,20 +46,15 @@ along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
android:maxLines="1"
|
||||
android:layout_weight="1" />
|
||||
</LinearLayout>
|
||||
<ViewSwitcher
|
||||
android:id="@+id/switcher"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1">
|
||||
<org.yaaic.view.ConversationGallery
|
||||
android:id="@+id/deck"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_margin="0px"
|
||||
android:unselectedAlpha="100"
|
||||
android:spacing="5dp"
|
||||
android:padding="0dp" />
|
||||
</ViewSwitcher>
|
||||
<android.support.v4.view.ViewPager
|
||||
android:id="@+id/pager"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:layout_margin="0px"
|
||||
android:unselectedAlpha="100"
|
||||
android:spacing="5dp"
|
||||
android:padding="0dp" />
|
||||
<org.yaaic.view.ConversationSwitcher
|
||||
android:id="@+id/dots"
|
||||
android:layout_width="wrap_content"
|
||||
@ -70,7 +65,7 @@ along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
android:orientation="horizontal">
|
||||
<EditText
|
||||
android:id="@+id/input"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:inputType="textImeMultiLine"
|
||||
|
@ -26,14 +26,13 @@ import java.util.List;
|
||||
|
||||
import org.yaaic.R;
|
||||
import org.yaaic.Yaaic;
|
||||
import org.yaaic.adapter.DeckAdapter;
|
||||
import org.yaaic.adapter.ConversationPagerAdapter;
|
||||
import org.yaaic.adapter.MessageListAdapter;
|
||||
import org.yaaic.command.CommandParser;
|
||||
import org.yaaic.irc.IRCBinder;
|
||||
import org.yaaic.irc.IRCConnection;
|
||||
import org.yaaic.irc.IRCService;
|
||||
import org.yaaic.layout.NonScalingBackgroundDrawable;
|
||||
import org.yaaic.listener.ConversationClickListener;
|
||||
import org.yaaic.listener.ConversationListener;
|
||||
import org.yaaic.listener.ConversationSelectedListener;
|
||||
import org.yaaic.listener.ServerListener;
|
||||
@ -53,7 +52,6 @@ import org.yaaic.model.User;
|
||||
import org.yaaic.receiver.ConversationReceiver;
|
||||
import org.yaaic.receiver.ServerReceiver;
|
||||
import org.yaaic.view.ConversationSwitcher;
|
||||
import org.yaaic.view.MessageListView;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
@ -69,28 +67,27 @@ import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.speech.RecognizerIntent;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.text.InputType;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.View.OnKeyListener;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.view.View.OnKeyListener;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Gallery;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import android.widget.ViewSwitcher;
|
||||
|
||||
/**
|
||||
* The server view with a scrollable list of all channels
|
||||
*
|
||||
*
|
||||
* @author Sebastian Kaspari <sebastian@yaaic.org>
|
||||
*/
|
||||
public class ConversationActivity extends Activity implements ServiceConnection, ServerListener, ConversationListener
|
||||
@ -108,9 +105,9 @@ public class ConversationActivity extends Activity implements ServiceConnection,
|
||||
private ConversationReceiver channelReceiver;
|
||||
private ServerReceiver serverReceiver;
|
||||
|
||||
private ViewSwitcher switcher;
|
||||
private Gallery deck;
|
||||
private DeckAdapter deckAdapter;
|
||||
private ViewPager pager;
|
||||
private ConversationPagerAdapter pagerAdapter;
|
||||
|
||||
private Scrollback scrollback;
|
||||
private ConversationSwitcher dots;
|
||||
|
||||
@ -202,23 +199,32 @@ public class ConversationActivity extends Activity implements ServiceConnection,
|
||||
EditText input = (EditText) findViewById(R.id.input);
|
||||
input.setOnKeyListener(inputKeyListener);
|
||||
|
||||
switcher = (ViewSwitcher) findViewById(R.id.switcher);
|
||||
pager = (ViewPager) findViewById(R.id.pager);
|
||||
|
||||
dots = (ConversationSwitcher) findViewById(R.id.dots);
|
||||
dots.setServer(server);
|
||||
|
||||
deckAdapter = new DeckAdapter();
|
||||
deck = (Gallery) findViewById(R.id.deck);
|
||||
deck.setOnItemSelectedListener(new ConversationSelectedListener(this, server, (TextView) findViewById(R.id.title), dots));
|
||||
deck.setAdapter(deckAdapter);
|
||||
deck.setOnItemClickListener(new ConversationClickListener(deckAdapter, switcher));
|
||||
deck.setBackgroundDrawable(new NonScalingBackgroundDrawable(this, deck, R.drawable.background));
|
||||
pagerAdapter = new ConversationPagerAdapter();
|
||||
pager.setAdapter(pagerAdapter);
|
||||
pager.setPageMargin(5);
|
||||
|
||||
pager.setOnPageChangeListener(
|
||||
new ConversationSelectedListener(
|
||||
this,
|
||||
server,
|
||||
(TextView) findViewById(R.id.title),
|
||||
pagerAdapter,
|
||||
dots
|
||||
)
|
||||
);
|
||||
|
||||
pager.setBackgroundDrawable(new NonScalingBackgroundDrawable(this, pager, R.drawable.background));
|
||||
|
||||
historySize = settings.getHistorySize();
|
||||
|
||||
if (server.getStatus() == Status.PRE_CONNECTING) {
|
||||
server.clearConversations();
|
||||
deckAdapter.clearConversations();
|
||||
pagerAdapter.clearConversations();
|
||||
server.getConversation(ServerInfo.DEFAULT_NAME).setHistorySize(historySize);
|
||||
}
|
||||
|
||||
@ -313,14 +319,14 @@ public class ConversationActivity extends Activity implements ServiceConnection,
|
||||
// Fill view with messages that have been buffered while paused
|
||||
for (Conversation conversation : mConversations) {
|
||||
String name = conversation.getName();
|
||||
mAdapter = deckAdapter.getItemAdapter(name);
|
||||
mAdapter = pagerAdapter.getItemAdapter(name);
|
||||
|
||||
if (mAdapter != null) {
|
||||
mAdapter.addBulkMessages(conversation.getBuffer());
|
||||
conversation.clearBuffer();
|
||||
} else {
|
||||
// Was conversation created while we were paused?
|
||||
if (deckAdapter.getPositionByName(name) == -1) {
|
||||
if (pagerAdapter.getPositionByName(name) == -1) {
|
||||
onNewConversation(name);
|
||||
}
|
||||
}
|
||||
@ -336,11 +342,11 @@ public class ConversationActivity extends Activity implements ServiceConnection,
|
||||
}
|
||||
|
||||
// Remove views for conversations that ended while we were paused
|
||||
int numViews = deckAdapter.getCount();
|
||||
int numViews = pagerAdapter.getCount();
|
||||
if (numViews > mConversations.size()) {
|
||||
for (int i = 0; i < numViews; ++i) {
|
||||
if (!mConversations.contains(deckAdapter.getItem(i))) {
|
||||
deckAdapter.removeItem(i--);
|
||||
if (!mConversations.contains(pagerAdapter.getItem(i))) {
|
||||
pagerAdapter.removeConversation(i--);
|
||||
--numViews;
|
||||
}
|
||||
}
|
||||
@ -379,33 +385,6 @@ public class ConversationActivity extends Activity implements ServiceConnection,
|
||||
unregisterReceiver(serverReceiver);
|
||||
}
|
||||
|
||||
/**
|
||||
* On save instance state (e.g. before a configuration change)
|
||||
*/
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState)
|
||||
{
|
||||
super.onSaveInstanceState(outState);
|
||||
|
||||
if (deckAdapter.isSwitched()) {
|
||||
outState.putBoolean("isSwitched", deckAdapter.isSwitched());
|
||||
outState.putString("switchedName", deckAdapter.getSwitchedName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* On restore instance state (e.g. after a configuration change)
|
||||
*/
|
||||
@Override
|
||||
protected void onRestoreInstanceState(Bundle inState)
|
||||
{
|
||||
super.onRestoreInstanceState(inState);
|
||||
|
||||
if (inState.getBoolean("isSwitched")) {
|
||||
deckAdapter.setSwitched(inState.getString("switchedName"), null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* On service connected
|
||||
*/
|
||||
@ -477,7 +456,7 @@ public class ConversationActivity extends Activity implements ServiceConnection,
|
||||
break;
|
||||
|
||||
case R.id.close:
|
||||
Conversation conversationToClose = deckAdapter.getItem(deck.getSelectedItemPosition());
|
||||
Conversation conversationToClose = pagerAdapter.getItem(pager.getCurrentItem());
|
||||
// Make sure we part a channel when closing the channel conversation
|
||||
if (conversationToClose.getType() == Conversation.TYPE_CHANNEL) {
|
||||
binder.getService().getConnection(serverId).partChannel(conversationToClose.getName());
|
||||
@ -495,15 +474,15 @@ public class ConversationActivity extends Activity implements ServiceConnection,
|
||||
break;
|
||||
|
||||
case R.id.users:
|
||||
Conversation conversationForUserList = deckAdapter.getItem(deck.getSelectedItemPosition());
|
||||
Conversation conversationForUserList = pagerAdapter.getItem(pager.getCurrentItem());
|
||||
if (conversationForUserList.getType() == Conversation.TYPE_CHANNEL) {
|
||||
Intent intent = new Intent(this, UsersActivity.class);
|
||||
intent.putExtra(
|
||||
Extra.USERS,
|
||||
binder.getService().getConnection(server.getId()).getUsersAsStringArray(
|
||||
conversationForUserList.getName()
|
||||
)
|
||||
);
|
||||
Extra.USERS,
|
||||
binder.getService().getConnection(server.getId()).getUsersAsStringArray(
|
||||
conversationForUserList.getName()
|
||||
)
|
||||
);
|
||||
startActivityForResult(intent, REQUEST_CODE_USERS);
|
||||
} else {
|
||||
Toast.makeText(this, getResources().getString(R.string.only_usable_from_channel), Toast.LENGTH_SHORT).show();
|
||||
@ -516,7 +495,7 @@ public class ConversationActivity extends Activity implements ServiceConnection,
|
||||
|
||||
/**
|
||||
* Get server object assigned to this activity
|
||||
*
|
||||
*
|
||||
* @return the server object
|
||||
*/
|
||||
public Server getServer()
|
||||
@ -538,7 +517,7 @@ public class ConversationActivity extends Activity implements ServiceConnection,
|
||||
return;
|
||||
}
|
||||
|
||||
MessageListAdapter adapter = deckAdapter.getItemAdapter(target);
|
||||
MessageListAdapter adapter = pagerAdapter.getItemAdapter(target);
|
||||
|
||||
while(conversation.hasBufferedMessages()) {
|
||||
Message message = conversation.pollBufferedMessage();
|
||||
@ -574,14 +553,18 @@ public class ConversationActivity extends Activity implements ServiceConnection,
|
||||
{
|
||||
createNewConversation(target);
|
||||
|
||||
if (!deckAdapter.isSwitched()) {
|
||||
// Scroll to new conversation
|
||||
deck.setSelection(deckAdapter.getCount() - 1);
|
||||
}
|
||||
pager.setCurrentItem(pagerAdapter.getCount() - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new conversation in the pager adapter for the
|
||||
* given target conversation.
|
||||
*
|
||||
* @param target
|
||||
*/
|
||||
public void createNewConversation(String target)
|
||||
{
|
||||
deckAdapter.addItem(server.getConversation(target));
|
||||
pagerAdapter.addConversation(server.getConversation(target));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -590,18 +573,17 @@ public class ConversationActivity extends Activity implements ServiceConnection,
|
||||
@Override
|
||||
public void onRemoveConversation(String target)
|
||||
{
|
||||
deckAdapter.removeItem(target);
|
||||
int position = pagerAdapter.getPositionByName(target);
|
||||
|
||||
if (deckAdapter.isSwitched()) {
|
||||
switcher.showNext();
|
||||
switcher.removeView(deckAdapter.getSwitchedView());
|
||||
deckAdapter.setSwitched(null, null);
|
||||
if (position != -1) {
|
||||
pagerAdapter.removeConversation(position);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* On topic change
|
||||
*/
|
||||
@Override
|
||||
public void onTopicChanged(String target)
|
||||
{
|
||||
String selected = server.getSelectedConversation();
|
||||
@ -654,8 +636,8 @@ public class ConversationActivity extends Activity implements ServiceConnection,
|
||||
return;
|
||||
}
|
||||
binder.getService().getConnection(server.getId()).setAutojoinChannels(
|
||||
server.getCurrentChannelNames()
|
||||
);
|
||||
server.getCurrentChannelNames()
|
||||
);
|
||||
server.setStatus(Status.CONNECTING);
|
||||
binder.connect(server);
|
||||
reconnectDialogActive = false;
|
||||
@ -675,25 +657,6 @@ public class ConversationActivity extends Activity implements ServiceConnection,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* On key down
|
||||
*
|
||||
* XXX: As we only track the back key: Android >= 2.0 will call a method called onBackPressed()
|
||||
*/
|
||||
@Override
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event)
|
||||
{
|
||||
if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
|
||||
if (deckAdapter.isSwitched()) {
|
||||
MessageListView canvas = (MessageListView) deckAdapter.getView(deckAdapter.getPositionByName(deckAdapter.getSwitchedName()), null, switcher);
|
||||
canvas.setSwitched(false);
|
||||
deckAdapter.setSwitched(null, null);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return super.onKeyDown(keyCode, event);
|
||||
}
|
||||
|
||||
/**
|
||||
* On activity result
|
||||
*/
|
||||
@ -746,11 +709,11 @@ public class ConversationActivity extends Activity implements ServiceConnection,
|
||||
String nicknameWithoutPrefix = nickname;
|
||||
|
||||
while (
|
||||
nicknameWithoutPrefix.startsWith("@") ||
|
||||
nicknameWithoutPrefix.startsWith("+") ||
|
||||
nicknameWithoutPrefix.startsWith(".") ||
|
||||
nicknameWithoutPrefix.startsWith("%")
|
||||
) {
|
||||
nicknameWithoutPrefix.startsWith("@") ||
|
||||
nicknameWithoutPrefix.startsWith("+") ||
|
||||
nicknameWithoutPrefix.startsWith(".") ||
|
||||
nicknameWithoutPrefix.startsWith("%")
|
||||
) {
|
||||
// Strip prefix(es) now
|
||||
nicknameWithoutPrefix = nicknameWithoutPrefix.substring(1);
|
||||
}
|
||||
@ -776,10 +739,10 @@ public class ConversationActivity extends Activity implements ServiceConnection,
|
||||
server.addConversation(query);
|
||||
|
||||
Intent intent = Broadcast.createConversationIntent(
|
||||
Broadcast.CONVERSATION_NEW,
|
||||
server.getId(),
|
||||
nicknameWithoutPrefix
|
||||
);
|
||||
Broadcast.CONVERSATION_NEW,
|
||||
server.getId(),
|
||||
nicknameWithoutPrefix
|
||||
);
|
||||
binder.getService().sendBroadcast(intent);
|
||||
}
|
||||
break;
|
||||
@ -830,7 +793,7 @@ public class ConversationActivity extends Activity implements ServiceConnection,
|
||||
|
||||
scrollback.addMessage(text);
|
||||
|
||||
Conversation conversation = deckAdapter.getItem(deck.getSelectedItemPosition());
|
||||
Conversation conversation = pagerAdapter.getItem(pager.getCurrentItem());
|
||||
|
||||
if (conversation != null) {
|
||||
if (!text.trim().startsWith("/")) {
|
||||
@ -907,14 +870,14 @@ public class ConversationActivity extends Activity implements ServiceConnection,
|
||||
}
|
||||
// Log.d("Yaaic", "Trying to complete nick: " + word);
|
||||
|
||||
Conversation conversationForUserList = deckAdapter.getItem(deck.getSelectedItemPosition());
|
||||
Conversation conversationForUserList = pagerAdapter.getItem(pager.getCurrentItem());
|
||||
|
||||
String[] users = null;
|
||||
|
||||
if (conversationForUserList.getType() == Conversation.TYPE_CHANNEL) {
|
||||
users = binder.getService().getConnection(server.getId()).getUsersAsStringArray(
|
||||
conversationForUserList.getName()
|
||||
);
|
||||
conversationForUserList.getName()
|
||||
);
|
||||
}
|
||||
|
||||
// go through users and add matches
|
||||
@ -987,7 +950,7 @@ public class ConversationActivity extends Activity implements ServiceConnection,
|
||||
|
||||
/**
|
||||
* Remove the status char off the front of a nick if one is present
|
||||
*
|
||||
*
|
||||
* @param nick
|
||||
* @return nick without statuschar
|
||||
*/
|
||||
@ -995,7 +958,7 @@ public class ConversationActivity extends Activity implements ServiceConnection,
|
||||
{
|
||||
/* Discard status characters */
|
||||
if (nick.startsWith("@") || nick.startsWith("+")
|
||||
|| nick.startsWith("%")) {
|
||||
|| nick.startsWith("%")) {
|
||||
nick = nick.substring(1);
|
||||
}
|
||||
return nick;
|
||||
|
@ -17,31 +17,33 @@ GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
*/
|
||||
package org.yaaic.adapter;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
|
||||
import org.yaaic.listener.MessageClickListener;
|
||||
import org.yaaic.model.Conversation;
|
||||
import org.yaaic.view.MessageListView;
|
||||
|
||||
import android.support.v4.view.PagerAdapter;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.TextView;
|
||||
|
||||
/**
|
||||
* The adapter for the "DeckView"
|
||||
*
|
||||
* Adapter for displaying a pager of conversations.
|
||||
*
|
||||
* @author Sebastian Kaspari <sebastian@yaaic.org>
|
||||
*/
|
||||
public class DeckAdapter extends BaseAdapter
|
||||
public class ConversationPagerAdapter extends PagerAdapter
|
||||
{
|
||||
private LinkedList<ConversationInfo> conversations;
|
||||
private MessageListView currentView;
|
||||
private String currentChannel;
|
||||
private final HashMap<Integer, View> views;
|
||||
|
||||
/**
|
||||
* Container class to remember conversation and view association.
|
||||
*/
|
||||
public class ConversationInfo {
|
||||
public Conversation conv;
|
||||
public MessageListAdapter adapter;
|
||||
@ -55,44 +57,51 @@ public class DeckAdapter extends BaseAdapter
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new DeckAdapter instance
|
||||
* Create a new {@link ConversationPagerAdapter} instance.
|
||||
*/
|
||||
public DeckAdapter()
|
||||
{
|
||||
public ConversationPagerAdapter() {
|
||||
conversations = new LinkedList<ConversationInfo>();
|
||||
views = new HashMap<Integer, View>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear conversations
|
||||
* Add a conversation to the adapter.
|
||||
*
|
||||
* @param conversation
|
||||
*/
|
||||
public void clearConversations()
|
||||
{
|
||||
conversations = new LinkedList<ConversationInfo>();
|
||||
public void addConversation(Conversation conversation) {
|
||||
conversations.add(new ConversationInfo(conversation));
|
||||
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get number of item
|
||||
* Remove the conversation at the given position from the adapter.
|
||||
*
|
||||
* @param position
|
||||
*/
|
||||
public void removeConversation(int position) {
|
||||
conversations.remove(position);
|
||||
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get position of given item.
|
||||
*/
|
||||
@Override
|
||||
public int getCount()
|
||||
public int getItemPosition(Object object)
|
||||
{
|
||||
return conversations.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ConversationInfo on item at position
|
||||
*/
|
||||
private ConversationInfo getItemInfo(int position) {
|
||||
if (position >= 0 && position < conversations.size()) {
|
||||
return conversations.get(position);
|
||||
if (views.containsKey(object)) {
|
||||
return POSITION_UNCHANGED;
|
||||
}
|
||||
return null;
|
||||
|
||||
return POSITION_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get item at position
|
||||
*/
|
||||
@Override
|
||||
public Conversation getItem(int position)
|
||||
{
|
||||
ConversationInfo convInfo = getItemInfo(position);
|
||||
@ -104,11 +113,13 @@ public class DeckAdapter extends BaseAdapter
|
||||
}
|
||||
|
||||
/**
|
||||
* Get MessageListAdapter belonging to a conversation
|
||||
* Get the adapter of the {@link MessageListView} at the given position.
|
||||
*
|
||||
* @param position Position of the conversation in the deck
|
||||
* @param position
|
||||
* @return
|
||||
*/
|
||||
public MessageListAdapter getItemAdapter(int position) {
|
||||
public MessageListAdapter getItemAdapter(int position)
|
||||
{
|
||||
ConversationInfo convInfo = getItemInfo(position);
|
||||
if (convInfo != null) {
|
||||
return convInfo.adapter;
|
||||
@ -118,39 +129,32 @@ public class DeckAdapter extends BaseAdapter
|
||||
}
|
||||
|
||||
/**
|
||||
* Get MessageListAdapter belonging to a conversation
|
||||
* Get the adapter of the {@link MessageListView} for the conversation
|
||||
* with the given name.
|
||||
*
|
||||
* @param name Name of the conversation
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
public MessageListAdapter getItemAdapter(String name) {
|
||||
public MessageListAdapter getItemAdapter(String name)
|
||||
{
|
||||
return getItemAdapter(getPositionByName(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get id of item at position
|
||||
* Get ConversationInfo on item at position
|
||||
*
|
||||
* @param position
|
||||
*/
|
||||
@Override
|
||||
public long getItemId(int position)
|
||||
{
|
||||
return position;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an item
|
||||
*
|
||||
* @param channel Name of the channel
|
||||
* @param view The view object
|
||||
*/
|
||||
public void addItem(Conversation conversation)
|
||||
{
|
||||
conversations.add(new ConversationInfo(conversation));
|
||||
|
||||
notifyDataSetChanged();
|
||||
private ConversationInfo getItemInfo(int position) {
|
||||
if (position >= 0 && position < conversations.size()) {
|
||||
return conversations.get(position);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an item by the channel's name
|
||||
*
|
||||
*
|
||||
* @param channel
|
||||
* @return The item
|
||||
*/
|
||||
@ -170,102 +174,62 @@ public class DeckAdapter extends BaseAdapter
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an item
|
||||
*
|
||||
* @param position
|
||||
* Remove all conversations.
|
||||
*/
|
||||
public void removeItem(int position)
|
||||
public void clearConversations()
|
||||
{
|
||||
if (position >= 0 && position < conversations.size()) {
|
||||
conversations.remove(position);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
conversations = new LinkedList<ConversationInfo>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an item
|
||||
*
|
||||
* @param target
|
||||
*/
|
||||
public void removeItem(String target)
|
||||
{
|
||||
removeItem(getPositionByName(target));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set single channel view
|
||||
*
|
||||
* @param switched
|
||||
*/
|
||||
public void setSwitched(String channel, MessageListView current)
|
||||
{
|
||||
currentChannel = channel;
|
||||
currentView = current;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get single channel view
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public MessageListView getSwitchedView()
|
||||
{
|
||||
return currentView;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name of channel (single channel view)
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getSwitchedName()
|
||||
{
|
||||
return currentChannel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Has the view been switched to single channel view?
|
||||
*
|
||||
* @return view true if view is in single channel view, false otherwise
|
||||
*/
|
||||
public boolean isSwitched()
|
||||
{
|
||||
return currentChannel != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get view at given position
|
||||
* Get number of conversations from this adapter.
|
||||
*/
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent)
|
||||
public int getCount()
|
||||
{
|
||||
ConversationInfo convInfo = getItemInfo(position);
|
||||
|
||||
// Market stack traces prove that sometimes we get a null converstion
|
||||
// because the collection changed while a view is requested for an
|
||||
// item that does not exist anymore... so we just need to reply with
|
||||
// some kind of view here.
|
||||
if (convInfo == null || convInfo.conv == null) {
|
||||
return new TextView(parent.getContext());
|
||||
}
|
||||
|
||||
if (convInfo.view != null) {
|
||||
return convInfo.view;
|
||||
} else {
|
||||
return renderConversation(convInfo, parent);
|
||||
}
|
||||
return conversations.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a conversation view (MessageListView)
|
||||
*
|
||||
* @param channel The conversation of the view
|
||||
* @param parent The parent view (context)
|
||||
* @return The rendered MessageListView
|
||||
* Determines whether a page View is associated with a specific key object.
|
||||
*/
|
||||
private MessageListView renderConversation(ConversationInfo convInfo, ViewGroup parent)
|
||||
@Override
|
||||
public boolean isViewFromObject(View view, Object object)
|
||||
{
|
||||
MessageListView list = new MessageListView(parent.getContext(), parent);
|
||||
return view == object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a view object for the conversation at the given position.
|
||||
*/
|
||||
@Override
|
||||
public Object instantiateItem(View collection, int position) {
|
||||
// ConversationInfo convInfo = getItemInfo(position);
|
||||
ConversationInfo convInfo = conversations.get(position);
|
||||
View view;
|
||||
|
||||
if (convInfo.view != null) {
|
||||
view = convInfo.view;
|
||||
} else {
|
||||
view = renderConversation(convInfo, collection);
|
||||
}
|
||||
|
||||
views.put(position, view);
|
||||
((ViewPager) collection).addView(view);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the given conversation and return the new view.
|
||||
*
|
||||
* @param convInfo
|
||||
* @param parent
|
||||
* @return
|
||||
*/
|
||||
private MessageListView renderConversation(ConversationInfo convInfo, View parent)
|
||||
{
|
||||
MessageListView list = new MessageListView(parent.getContext());
|
||||
convInfo.view = list;
|
||||
list.setOnItemClickListener(MessageClickListener.getInstance());
|
||||
|
||||
@ -279,11 +243,15 @@ public class DeckAdapter extends BaseAdapter
|
||||
list.setAdapter(adapter);
|
||||
list.setSelection(adapter.getCount() - 1); // scroll to bottom
|
||||
|
||||
if (convInfo.conv.getName().equals(currentChannel)) {
|
||||
list.setSwitched(true);
|
||||
currentView = list;
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the given view from the adapter and collection.
|
||||
*/
|
||||
@Override
|
||||
public void destroyItem(View collection, int position, Object view) {
|
||||
((ViewPager) collection).removeView((View) view);
|
||||
views.remove(position);
|
||||
}
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2011 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
Yaaic is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Yaaic is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.yaaic.listener;
|
||||
|
||||
import org.yaaic.adapter.DeckAdapter;
|
||||
import org.yaaic.model.Conversation;
|
||||
import org.yaaic.view.MessageListView;
|
||||
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.AdapterView.OnItemClickListener;
|
||||
import android.widget.ViewSwitcher;
|
||||
|
||||
/**
|
||||
* Listener for clicks on conversations
|
||||
*
|
||||
* @author Sebastian Kaspari <sebastian@yaaic.org>
|
||||
*/
|
||||
public class ConversationClickListener implements OnItemClickListener
|
||||
{
|
||||
private final DeckAdapter adapter;
|
||||
private final ViewSwitcher switcher;
|
||||
|
||||
/**
|
||||
* Create a new ConversationClickListener
|
||||
*
|
||||
* @param adapter
|
||||
* @param switcher
|
||||
*/
|
||||
public ConversationClickListener(DeckAdapter adapter, ViewSwitcher switcher)
|
||||
{
|
||||
this.adapter = adapter;
|
||||
this.switcher = switcher;
|
||||
}
|
||||
|
||||
/**
|
||||
* On conversation item clicked
|
||||
*/
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id)
|
||||
{
|
||||
Conversation conversation = adapter.getItem(position);
|
||||
|
||||
MessageListView canvas = (MessageListView) adapter.getView(position, null, switcher);
|
||||
canvas.setSwitched(true);
|
||||
adapter.setSwitched(conversation.getName(), canvas);
|
||||
}
|
||||
}
|
@ -20,61 +20,63 @@ along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.yaaic.listener;
|
||||
|
||||
import org.yaaic.adapter.ConversationPagerAdapter;
|
||||
import org.yaaic.irc.IRCService;
|
||||
import org.yaaic.model.Channel;
|
||||
import org.yaaic.model.Conversation;
|
||||
import org.yaaic.model.Server;
|
||||
import org.yaaic.view.ConversationSwitcher;
|
||||
import org.yaaic.irc.IRCService;
|
||||
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.AdapterView.OnItemSelectedListener;
|
||||
import android.widget.TextView;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.support.v4.view.ViewPager.OnPageChangeListener;
|
||||
import android.widget.TextView;
|
||||
|
||||
/**
|
||||
* Listener for conversation selections
|
||||
*
|
||||
*
|
||||
* @author Sebastian Kaspari <sebastian@yaaic.org>
|
||||
*/
|
||||
public class ConversationSelectedListener implements OnItemSelectedListener
|
||||
public class ConversationSelectedListener implements OnPageChangeListener
|
||||
{
|
||||
private final Context ctx;
|
||||
private final Server server;
|
||||
private final TextView titleView;
|
||||
private final ConversationSwitcher switcher;
|
||||
private final ConversationPagerAdapter adapter;
|
||||
|
||||
/**
|
||||
* Create a new ConversationSelectedListener
|
||||
*
|
||||
*
|
||||
* @param server
|
||||
* @param titleView
|
||||
*/
|
||||
public ConversationSelectedListener(Context ctx, Server server, TextView titleView, ConversationSwitcher switcher)
|
||||
public ConversationSelectedListener(Context ctx, Server server, TextView titleView, ConversationPagerAdapter adapter, ConversationSwitcher switcher)
|
||||
{
|
||||
this.ctx = ctx;
|
||||
this.server = server;
|
||||
this.titleView = titleView;
|
||||
this.switcher = switcher;
|
||||
this.adapter = adapter;
|
||||
}
|
||||
|
||||
/**
|
||||
* On conversation selected/focused
|
||||
* On page has been selected.
|
||||
*/
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> deck, View view, int position, long id)
|
||||
public void onPageSelected(int position)
|
||||
{
|
||||
Conversation conversation = (Conversation) deck.getItemAtPosition(position);
|
||||
Conversation conversation = adapter.getItem(position);
|
||||
|
||||
if (conversation != null && conversation.getType() != Conversation.TYPE_SERVER) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(server.getTitle() + " - " + conversation.getName());
|
||||
if (conversation.getType() == Conversation.TYPE_CHANNEL && !((Channel)conversation).getTopic().equals(""))
|
||||
if (conversation.getType() == Conversation.TYPE_CHANNEL && !((Channel)conversation).getTopic().equals("")) {
|
||||
sb.append(" - " + ((Channel)conversation).getTopic());
|
||||
}
|
||||
titleView.setText(sb.toString());
|
||||
} else {
|
||||
onNothingSelected(deck);
|
||||
titleView.setText(server.getTitle());
|
||||
}
|
||||
|
||||
// Remember selection
|
||||
@ -101,11 +103,18 @@ public class ConversationSelectedListener implements OnItemSelectedListener
|
||||
}
|
||||
|
||||
/**
|
||||
* On no conversation selected/focused
|
||||
* On scroll state of pager has been chanaged.
|
||||
*/
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> deck)
|
||||
public void onPageScrollStateChanged(int state)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* On page has been scrolled.
|
||||
*/
|
||||
@Override
|
||||
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels)
|
||||
{
|
||||
titleView.setText(server.getTitle());
|
||||
}
|
||||
}
|
||||
|
@ -1,60 +0,0 @@
|
||||
/*
|
||||
Yaaic - Yet Another Android IRC Client
|
||||
|
||||
Copyright 2009-2011 Sebastian Kaspari
|
||||
|
||||
This file is part of Yaaic.
|
||||
|
||||
Yaaic is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Yaaic is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Yaaic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.yaaic.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.widget.Gallery;
|
||||
|
||||
/**
|
||||
* Conversation gallery for horizontal scrolling
|
||||
*
|
||||
* @author Thomas Martitz
|
||||
*/
|
||||
public class ConversationGallery extends Gallery
|
||||
{
|
||||
/**
|
||||
* Create a new conversation gallery
|
||||
*
|
||||
* @param context
|
||||
* @param attrs
|
||||
*/
|
||||
public ConversationGallery(Context context, AttributeSet attrs)
|
||||
{
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
/**
|
||||
* On Fling: Reduce sensitivity of the channel gallery view
|
||||
*/
|
||||
@Override
|
||||
public boolean onFling (MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
|
||||
{
|
||||
/* Reduce sensitivity based on f(x) = x * 0.925^y with y = (|x/500| - 1)
|
||||
* The goal is to reduce higher velocities stronger than low ones
|
||||
* 500 is the base, i.e. it will not reduced. */
|
||||
final float fexp = Math.abs(velocityX / 500.0f) - 1;
|
||||
velocityX *= Math.pow(0.925, fexp);
|
||||
|
||||
return super.onFling(e1, e2, velocityX, velocityY);
|
||||
}
|
||||
}
|
@ -33,7 +33,7 @@ import android.view.View;
|
||||
|
||||
/**
|
||||
* The ConversationSwitcher - The small funny dots at the bottom ;)
|
||||
*
|
||||
*
|
||||
* @author Sebastian Kaspari <sebastian@yaaic.org>
|
||||
*/
|
||||
public class ConversationSwitcher extends View
|
||||
@ -43,7 +43,7 @@ public class ConversationSwitcher extends View
|
||||
|
||||
/**
|
||||
* Create a new ConversationSwitcher
|
||||
*
|
||||
*
|
||||
* @param context The Context the view is running in, through which it can access the current theme, resources, etc.
|
||||
*/
|
||||
public ConversationSwitcher(Context context, AttributeSet attributes)
|
||||
@ -56,7 +56,7 @@ public class ConversationSwitcher extends View
|
||||
|
||||
/**
|
||||
* Set the server whos conversations should be displayed
|
||||
*
|
||||
*
|
||||
* @param server
|
||||
*/
|
||||
public void setServer(Server server)
|
||||
@ -66,7 +66,7 @@ public class ConversationSwitcher extends View
|
||||
|
||||
/**
|
||||
* Measure the size of the view
|
||||
*
|
||||
*
|
||||
* @param widthMeasureSpec
|
||||
* @param heightMeasureSpec
|
||||
*/
|
||||
|
@ -25,46 +25,27 @@ import org.yaaic.adapter.MessageListAdapter;
|
||||
import org.yaaic.listener.MessageClickListener;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.widget.Gallery;
|
||||
import android.widget.ListView;
|
||||
|
||||
/**
|
||||
* A customized ListView for Messages
|
||||
*
|
||||
*
|
||||
* @author Sebastian Kaspari <sebastian@yaaic.org>
|
||||
*/
|
||||
public class MessageListView extends ListView
|
||||
{
|
||||
private boolean switched = false;
|
||||
private final View parent;
|
||||
private int parentWidth;
|
||||
private int parentHeight;
|
||||
private final int padding;
|
||||
private final int paddingWide;
|
||||
|
||||
/**
|
||||
* Create a new MessageListView
|
||||
*
|
||||
*
|
||||
* @param context
|
||||
*/
|
||||
public MessageListView(Context context, View parent)
|
||||
public MessageListView(Context context)
|
||||
{
|
||||
super(context);
|
||||
|
||||
this.parent = parent;
|
||||
setOnItemClickListener(MessageClickListener.getInstance());
|
||||
|
||||
parentWidth = parent.getWidth();
|
||||
parentHeight = parent.getHeight();
|
||||
|
||||
setDivider(null);
|
||||
setLayoutParams(new Gallery.LayoutParams(
|
||||
parentWidth*85/100,
|
||||
parentHeight
|
||||
));
|
||||
|
||||
setBackgroundResource(R.layout.rounded);
|
||||
setCacheColorHint(0xee000000);
|
||||
@ -74,52 +55,17 @@ public class MessageListView extends ListView
|
||||
|
||||
// Scale padding by screen density
|
||||
float density = context.getResources().getDisplayMetrics().density;
|
||||
padding = (int)(5 * density);
|
||||
paddingWide = (int)(12 * density);
|
||||
int padding = (int) (5 * density);
|
||||
setPadding(padding, padding, padding, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle touch screen motion events
|
||||
*/
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event)
|
||||
{
|
||||
if (!switched) {
|
||||
// We delegate the touch events to the underlying view
|
||||
return false;
|
||||
} else {
|
||||
return super.onTouchEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* On draw
|
||||
*/
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas)
|
||||
{
|
||||
if (parent.getWidth() != parentWidth || parent.getHeight() != parentHeight) {
|
||||
// parent size changed, resizing this child too
|
||||
|
||||
parentWidth = parent.getWidth();
|
||||
parentHeight = parent.getHeight();
|
||||
|
||||
if (!switched) {
|
||||
setLayoutParams(new Gallery.LayoutParams(
|
||||
parentWidth*85/100,
|
||||
parentHeight
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
super.onDraw(canvas);
|
||||
// XXX: This should be dynamically
|
||||
setTranscriptMode(TRANSCRIPT_MODE_ALWAYS_SCROLL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the adapter of this MessageListView
|
||||
* (Helper to avoid casting)
|
||||
*
|
||||
*
|
||||
* @return The MessageListAdapter
|
||||
*/
|
||||
@Override
|
||||
@ -127,23 +73,4 @@ public class MessageListView extends ListView
|
||||
{
|
||||
return (MessageListAdapter) super.getAdapter();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether this conversation is switched (taking up all of deck's space
|
||||
* and handling touch events itself)
|
||||
*/
|
||||
public void setSwitched(boolean switched)
|
||||
{
|
||||
this.switched = switched;
|
||||
|
||||
if (switched) {
|
||||
setLayoutParams(new Gallery.LayoutParams(Gallery.LayoutParams.FILL_PARENT, Gallery.LayoutParams.FILL_PARENT));
|
||||
setTranscriptMode(TRANSCRIPT_MODE_NORMAL);
|
||||
setPadding(paddingWide, padding, paddingWide, 0);
|
||||
} else {
|
||||
setLayoutParams(new Gallery.LayoutParams(parentWidth*85/100, parentHeight));
|
||||
setTranscriptMode(TRANSCRIPT_MODE_ALWAYS_SCROLL);
|
||||
setPadding(padding, padding, padding, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user