From 810fd66e4e0f5bbb67e3e142ae7ab8537092ad99 Mon Sep 17 00:00:00 2001 From: Floens Date: Sun, 12 Jul 2015 22:26:45 +0200 Subject: [PATCH] Add board selecting to filterlayout --- .../chan/core/manager/FilterEngine.java | 17 ++ .../org/floens/chan/core/model/Filter.java | 28 ++ .../ui/controller/BoardEditController.java | 7 +- .../chan/ui/controller/FiltersController.java | 7 +- .../floens/chan/ui/helper/BoardHelper.java | 31 +++ .../chan/ui/layout/BoardSelectLayout.java | 263 ++++++++++++++++++ .../floens/chan/ui/layout/FilterLayout.java | 117 +++++++- .../floens/chan/ui/layout/SearchLayout.java | 141 ++++++++++ .../org/floens/chan/ui/toolbar/Toolbar.java | 83 ++---- .../src/main/res/layout/cell_board_select.xml | 58 ++++ .../main/res/layout/layout_board_select.xml | 54 ++++ .../app/src/main/res/layout/layout_filter.xml | 49 +++- Clover/app/src/main/res/values/strings.xml | 4 + 13 files changed, 762 insertions(+), 97 deletions(-) create mode 100644 Clover/app/src/main/java/org/floens/chan/ui/helper/BoardHelper.java create mode 100644 Clover/app/src/main/java/org/floens/chan/ui/layout/BoardSelectLayout.java create mode 100644 Clover/app/src/main/java/org/floens/chan/ui/layout/SearchLayout.java create mode 100644 Clover/app/src/main/res/layout/cell_board_select.xml create mode 100644 Clover/app/src/main/res/layout/layout_board_select.xml diff --git a/Clover/app/src/main/java/org/floens/chan/core/manager/FilterEngine.java b/Clover/app/src/main/java/org/floens/chan/core/manager/FilterEngine.java index 758c7073..4be97dff 100644 --- a/Clover/app/src/main/java/org/floens/chan/core/manager/FilterEngine.java +++ b/Clover/app/src/main/java/org/floens/chan/core/manager/FilterEngine.java @@ -1,3 +1,20 @@ +/* + * Clover - 4chan browser https://github.com/Floens/Clover/ + * Copyright (C) 2014 Floens + * + * This program 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. + * + * This program 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 this program. If not, see . + */ package org.floens.chan.core.manager; import org.floens.chan.core.model.Filter; diff --git a/Clover/app/src/main/java/org/floens/chan/core/model/Filter.java b/Clover/app/src/main/java/org/floens/chan/core/model/Filter.java index bf5e1f06..100f4603 100644 --- a/Clover/app/src/main/java/org/floens/chan/core/model/Filter.java +++ b/Clover/app/src/main/java/org/floens/chan/core/model/Filter.java @@ -1,3 +1,20 @@ +/* + * Clover - 4chan browser https://github.com/Floens/Clover/ + * Copyright (C) 2014 Floens + * + * This program 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. + * + * This program 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 this program. If not, see . + */ package org.floens.chan.core.model; public class Filter { @@ -9,7 +26,18 @@ public class Filter { public String pattern; + public boolean allBoards = true; + public String boards; public boolean hide = true; + + public void apply(Filter filter) { + enabled = filter.enabled; + type = filter.type; + pattern = filter.pattern; + allBoards = filter.allBoards; + boards = filter.boards; + hide = filter.hide; + } } diff --git a/Clover/app/src/main/java/org/floens/chan/ui/controller/BoardEditController.java b/Clover/app/src/main/java/org/floens/chan/ui/controller/BoardEditController.java index a1c6769f..3c3318e3 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/controller/BoardEditController.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/controller/BoardEditController.java @@ -45,12 +45,12 @@ import org.floens.chan.controller.Controller; import org.floens.chan.core.manager.BoardManager; import org.floens.chan.core.model.Board; import org.floens.chan.ui.drawable.ThumbDrawable; +import org.floens.chan.ui.helper.BoardHelper; import org.floens.chan.ui.helper.SwipeListener; import org.floens.chan.ui.toolbar.ToolbarMenu; import org.floens.chan.ui.toolbar.ToolbarMenuItem; import org.floens.chan.ui.view.FloatingMenuItem; import org.floens.chan.utils.AndroidUtils; -import org.jsoup.parser.Parser; import java.util.ArrayList; import java.util.Collections; @@ -396,9 +396,8 @@ public class BoardEditController extends Controller implements SwipeListener.Cal } else { BoardEditItem item = (BoardEditItem) holder; Board board = boards.get(position - 1); - item.text.setText("/" + board.value + "/ " + board.key); - - item.description.setText(board.description == null ? null : Parser.unescapeEntities(board.description, false)); + item.text.setText(BoardHelper.getName(board)); + item.description.setText(BoardHelper.getDescription(board)); } } diff --git a/Clover/app/src/main/java/org/floens/chan/ui/controller/FiltersController.java b/Clover/app/src/main/java/org/floens/chan/ui/controller/FiltersController.java index b7105c3b..c80f233f 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/controller/FiltersController.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/controller/FiltersController.java @@ -101,7 +101,7 @@ public class FiltersController extends Controller implements ToolbarMenuItem.Too public void onSubMenuItemClicked(ToolbarMenuItem parent, FloatingMenuItem item) { } - private void showFilterDialog(Filter filter) { + private void showFilterDialog(final Filter filter) { final FilterLayout filterLayout = (FilterLayout) LayoutInflater.from(context).inflate(R.layout.layout_filter, null); new AlertDialog.Builder(context) @@ -109,7 +109,10 @@ public class FiltersController extends Controller implements ToolbarMenuItem.Too .setPositiveButton(R.string.save, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - filterLayout.save(); + Filter newFilter = filterLayout.getFilter(); + newFilter.id = filter.id; + Chan.getDatabaseManager().addFilter(newFilter); + adapter.load(); } }) diff --git a/Clover/app/src/main/java/org/floens/chan/ui/helper/BoardHelper.java b/Clover/app/src/main/java/org/floens/chan/ui/helper/BoardHelper.java new file mode 100644 index 00000000..75af1482 --- /dev/null +++ b/Clover/app/src/main/java/org/floens/chan/ui/helper/BoardHelper.java @@ -0,0 +1,31 @@ +/* + * Clover - 4chan browser https://github.com/Floens/Clover/ + * Copyright (C) 2014 Floens + * + * This program 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. + * + * This program 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 this program. If not, see . + */ +package org.floens.chan.ui.helper; + +import org.floens.chan.core.model.Board; +import org.jsoup.parser.Parser; + +public class BoardHelper { + public static String getName(Board board) { + return "/" + board.value + "/ " + board.key; + } + + public static String getDescription(Board board) { + return board.description == null ? null : Parser.unescapeEntities(board.description, false); + } +} diff --git a/Clover/app/src/main/java/org/floens/chan/ui/layout/BoardSelectLayout.java b/Clover/app/src/main/java/org/floens/chan/ui/layout/BoardSelectLayout.java new file mode 100644 index 00000000..b8445c1b --- /dev/null +++ b/Clover/app/src/main/java/org/floens/chan/ui/layout/BoardSelectLayout.java @@ -0,0 +1,263 @@ +/* + * Clover - 4chan browser https://github.com/Floens/Clover/ + * Copyright (C) 2014 Floens + * + * This program 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. + * + * This program 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 this program. If not, see . + */ +package org.floens.chan.ui.layout; + +import android.content.Context; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.text.TextUtils; +import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.CheckBox; +import android.widget.CompoundButton; +import android.widget.LinearLayout; +import android.widget.TextView; + +import org.floens.chan.Chan; +import org.floens.chan.R; +import org.floens.chan.core.manager.BoardManager; +import org.floens.chan.core.model.Board; +import org.floens.chan.ui.helper.BoardHelper; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import static org.floens.chan.utils.AndroidUtils.getAttrColor; +import static org.floens.chan.utils.AndroidUtils.getString; + +public class BoardSelectLayout extends LinearLayout implements SearchLayout.SearchLayoutCallback, View.OnClickListener { + private SearchLayout searchLayout; + private RecyclerView recyclerView; + private Button checkAllButton; + + private List boards = new ArrayList<>(); + private BoardManager boardManager; + private BoardSelectAdapter adapter; + private boolean allChecked = false; + + public BoardSelectLayout(Context context) { + super(context); + } + + public BoardSelectLayout(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public BoardSelectLayout(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + } + + @Override + public void onSearchEntered(String entered) { + adapter.search(entered); + } + + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + + boardManager = Chan.getBoardManager(); + + List savedList = boardManager.getSavedBoards(); + for (Board saved : savedList) { + boards.add(new BoardChecked(saved, false)); + } + + searchLayout = (SearchLayout) findViewById(R.id.search_layout); + searchLayout.setCallback(this); + searchLayout.setHint(getString(R.string.search_hint)); + searchLayout.setTextColor(getAttrColor(getContext(), R.attr.text_color_primary)); + searchLayout.setHintColor(getAttrColor(getContext(), R.attr.text_color_hint)); + searchLayout.setClearButtonImage(R.drawable.ic_clear_black_24dp); + + checkAllButton = (Button) findViewById(R.id.select_all); + checkAllButton.setOnClickListener(this); + + recyclerView = (RecyclerView) findViewById(R.id.recycler_view); + recyclerView.setHasFixedSize(true); + recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); + + adapter = new BoardSelectAdapter(); + recyclerView.setAdapter(adapter); + adapter.load(); + + updateAllSelected(); + } + + @Override + public void onClick(View v) { + if (v == checkAllButton) { + for (BoardChecked item : boards) { + item.checked = !allChecked; + } + + updateAllSelected(); + recyclerView.getAdapter().notifyDataSetChanged(); + } + } + + public void setCheckedBoards(List checked) { + for (BoardChecked board : boards) { + for (Board check : checked) { + if (check.value.equals(board.board.value)) { + board.checked = true; + break; + } + } + } + + recyclerView.getAdapter().notifyDataSetChanged(); + } + + public List getCheckedBoards() { + List list = new ArrayList<>(); + for (int i = 0; i < boards.size(); i++) { + BoardSelectLayout.BoardChecked board = boards.get(i); + if (board.checked) { + list.add(board.board); + } + } + + return list; + } + + public boolean getAllChecked() { + return allChecked; + } + + private void updateAllSelected() { + int checkedCount = 0; + for (BoardChecked item : boards) { + if (item.checked) { + checkedCount++; + } + } + + allChecked = checkedCount == boards.size(); + checkAllButton.setText(allChecked ? R.string.board_select_none : R.string.board_select_all); + } + + private class BoardSelectAdapter extends RecyclerView.Adapter { + private List sourceList = new ArrayList<>(); + private List displayList = new ArrayList<>(); + private String searchQuery; + + public BoardSelectAdapter() { + setHasStableIds(true); + } + + @Override + public BoardSelectViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + return new BoardSelectViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.cell_board_select, parent, false)); + } + + @Override + public void onBindViewHolder(BoardSelectViewHolder holder, int position) { + BoardChecked board = displayList.get(position); + holder.checkBox.setChecked(board.checked); + holder.text.setText(BoardHelper.getName(board.board)); + holder.description.setText(BoardHelper.getDescription(board.board)); + } + + @Override + public int getItemCount() { + return displayList.size(); + } + + @Override + public long getItemId(int position) { + return displayList.get(position).board.id; + } + + public void search(String query) { + this.searchQuery = query; + filter(); + } + + private void load() { + sourceList.clear(); + sourceList.addAll(boards); + + filter(); + } + + private void filter() { + displayList.clear(); + if (!TextUtils.isEmpty(searchQuery)) { + String query = searchQuery.toLowerCase(Locale.ENGLISH); + for (BoardChecked boardChecked : sourceList) { + String description = boardChecked.board.description == null ? "" : boardChecked.board.description; + if (boardChecked.board.key.toLowerCase(Locale.ENGLISH).contains(query) || + boardChecked.board.value.toLowerCase(Locale.ENGLISH).contains(query) || + description.toLowerCase(Locale.ENGLISH).contains(query)) { + displayList.add(boardChecked); + } + } + } else { + displayList.addAll(sourceList); + } + + notifyDataSetChanged(); + } + } + + private class BoardSelectViewHolder extends RecyclerView.ViewHolder implements CompoundButton.OnCheckedChangeListener, OnClickListener { + private CheckBox checkBox; + private TextView text; + private TextView description; + + public BoardSelectViewHolder(View itemView) { + super(itemView); + checkBox = (CheckBox) itemView.findViewById(R.id.checkbox); + text = (TextView) itemView.findViewById(R.id.text); + description = (TextView) itemView.findViewById(R.id.description); + + checkBox.setOnCheckedChangeListener(this); + + itemView.setOnClickListener(this); + } + + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + if (buttonView == checkBox) { + BoardChecked board = adapter.displayList.get(getAdapterPosition()); + board.checked = isChecked; + updateAllSelected(); + } + } + + @Override + public void onClick(View v) { + checkBox.toggle(); + } + } + + public static class BoardChecked { + public Board board; + public boolean checked; + + public BoardChecked(Board board, boolean checked) { + this.board = board; + this.checked = checked; + } + } +} diff --git a/Clover/app/src/main/java/org/floens/chan/ui/layout/FilterLayout.java b/Clover/app/src/main/java/org/floens/chan/ui/layout/FilterLayout.java index 63e68acd..f39a28a1 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/layout/FilterLayout.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/layout/FilterLayout.java @@ -1,8 +1,29 @@ +/* + * Clover - 4chan browser https://github.com/Floens/Clover/ + * Copyright (C) 2014 Floens + * + * This program 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. + * + * This program 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 this program. If not, see . + */ package org.floens.chan.ui.layout; import android.content.Context; +import android.content.DialogInterface; +import android.support.v7.app.AlertDialog; +import android.text.TextUtils; import android.util.AttributeSet; import android.view.Gravity; +import android.view.LayoutInflater; import android.view.View; import android.widget.CheckBox; import android.widget.LinearLayout; @@ -10,7 +31,9 @@ import android.widget.TextView; import org.floens.chan.Chan; import org.floens.chan.R; +import org.floens.chan.core.manager.BoardManager; import org.floens.chan.core.manager.FilterEngine; +import org.floens.chan.core.model.Board; import org.floens.chan.core.model.Filter; import org.floens.chan.ui.drawable.DropdownArrowDrawable; import org.floens.chan.ui.view.FloatingMenu; @@ -25,11 +48,16 @@ import static org.floens.chan.utils.AndroidUtils.getString; public class FilterLayout extends LinearLayout implements View.OnClickListener, FloatingMenu.FloatingMenuCallback { private TextView typeText; - private TextView boards; + private TextView boardsSelector; private TextView pattern; + private CheckBox enabled; private CheckBox hide; - private Filter filter; + private BoardManager boardManager; + + private Filter filter = new Filter(); + + private List appliedBoards = new ArrayList<>(); public FilterLayout(Context context) { super(context); @@ -47,30 +75,55 @@ public class FilterLayout extends LinearLayout implements View.OnClickListener, protected void onFinishInflate() { super.onFinishInflate(); + boardManager = Chan.getBoardManager(); + typeText = (TextView) findViewById(R.id.type); - boards = (TextView) findViewById(R.id.boards); + boardsSelector = (TextView) findViewById(R.id.boards); pattern = (TextView) findViewById(R.id.pattern); + enabled = (CheckBox) findViewById(R.id.enabled); hide = (CheckBox) findViewById(R.id.hide); typeText.setOnClickListener(this); typeText.setCompoundDrawablesWithIntrinsicBounds(null, null, new DropdownArrowDrawable(dp(12), dp(12), true, getAttrColor(getContext(), R.attr.dropdown_dark_color), getAttrColor(getContext(), R.attr.dropdown_dark_pressed_color)), null); + + boardsSelector.setOnClickListener(this); + boardsSelector.setCompoundDrawablesWithIntrinsicBounds(null, null, new DropdownArrowDrawable(dp(12), dp(12), true, + getAttrColor(getContext(), R.attr.dropdown_dark_color), getAttrColor(getContext(), R.attr.dropdown_dark_pressed_color)), null); + + update(); } public void setFilter(Filter filter) { - this.filter = filter; - pattern.setText(filter.pattern); - boards.setText(filter.boards); - hide.setChecked(filter.hide); - - typeText.setText(filterTypeName(FilterEngine.FilterType.forId(filter.type))); + this.filter.apply(filter); + appliedBoards.clear(); + if (filter.allBoards) { + appliedBoards.addAll(boardManager.getSavedBoards()); + } else if (!TextUtils.isEmpty(filter.boards)) { + for (String value : filter.boards.split(",")) { + Board boardByValue = boardManager.getBoardByValue(value); + if (boardByValue != null) { + appliedBoards.add(boardByValue); + } + } + } + update(); } - public void save() { + public Filter getFilter() { filter.pattern = pattern.getText().toString(); - filter.boards = boards.getText().toString(); filter.hide = hide.isChecked(); + filter.enabled = enabled.isChecked(); + + filter.boards = ""; + for (int i = 0; i < appliedBoards.size(); i++) { + Board board = appliedBoards.get(i); + filter.boards += board.value; + if (i < appliedBoards.size() - 1) { + filter.boards += ","; + } + } - Chan.getDatabaseManager().addFilter(filter); + return filter; } @Override @@ -88,20 +141,58 @@ public class FilterLayout extends LinearLayout implements View.OnClickListener, menu.setCallback(this); menu.setItems(menuItems); menu.show(); + } else if (v == boardsSelector) { + final BoardSelectLayout boardSelectLayout = (BoardSelectLayout) LayoutInflater.from(getContext()).inflate(R.layout.layout_board_select, null); + + boardSelectLayout.setCheckedBoards(appliedBoards); + + new AlertDialog.Builder(getContext()) + .setView(boardSelectLayout) + .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + setCheckedBoards(boardSelectLayout.getCheckedBoards(), boardSelectLayout.getAllChecked()); + update(); + } + }) + .show(); } } @Override public void onFloatingMenuItemClicked(FloatingMenu menu, FloatingMenuItem item) { FilterEngine.FilterType type = (FilterEngine.FilterType) item.getId(); - typeText.setText(filterTypeName(type)); filter.type = type.id; + update(); } @Override public void onFloatingMenuDismissed(FloatingMenu menu) { } + private void update() { + pattern.setText(filter.pattern); + hide.setChecked(filter.hide); + enabled.setChecked(filter.enabled); + + typeText.setText(filterTypeName(FilterEngine.FilterType.forId(filter.type))); + + String text = getString(R.string.filter_boards) + " ("; + if (filter.allBoards) { + text += getString(R.string.filter_boards_all); + } else { + text += String.valueOf(appliedBoards.size()); + } + text += ")"; + boardsSelector.setText(text); + } + + private void setCheckedBoards(List checkedBoards, boolean allChecked) { + appliedBoards.clear(); + appliedBoards.addAll(checkedBoards); + filter.allBoards = allChecked; + } + private String filterTypeName(FilterEngine.FilterType type) { switch (type) { case TRIPCODE: diff --git a/Clover/app/src/main/java/org/floens/chan/ui/layout/SearchLayout.java b/Clover/app/src/main/java/org/floens/chan/ui/layout/SearchLayout.java new file mode 100644 index 00000000..ee712a55 --- /dev/null +++ b/Clover/app/src/main/java/org/floens/chan/ui/layout/SearchLayout.java @@ -0,0 +1,141 @@ +/* + * Clover - 4chan browser https://github.com/Floens/Clover/ + * Copyright (C) 2014 Floens + * + * This program 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. + * + * This program 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 this program. If not, see . + */ +package org.floens.chan.ui.layout; + +import android.content.Context; +import android.text.Editable; +import android.text.TextWatcher; +import android.util.AttributeSet; +import android.util.TypedValue; +import android.view.Gravity; +import android.view.KeyEvent; +import android.view.View; +import android.view.inputmethod.EditorInfo; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; + +import org.floens.chan.R; +import org.floens.chan.utils.AndroidUtils; + +import static org.floens.chan.utils.AndroidUtils.dp; + +public class SearchLayout extends LinearLayout { + private EditText searchView; + private ImageView clearButton; + + public SearchLayout(Context context) { + super(context); + } + + public SearchLayout(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public SearchLayout(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + public void setCallback(final SearchLayoutCallback callback) { + searchView = new EditText(getContext()); + searchView.setImeOptions(EditorInfo.IME_FLAG_NO_FULLSCREEN | EditorInfo.IME_ACTION_DONE); + searchView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18); + searchView.setHintTextColor(0x88ffffff); + searchView.setTextColor(0xffffffff); + searchView.setSingleLine(true); + searchView.setBackgroundResource(0); + searchView.setPadding(0, 0, 0, 0); + clearButton = new ImageView(getContext()); + searchView.addTextChangedListener(new TextWatcher() { + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + clearButton.setAlpha(s.length() == 0 ? 0.6f : 1.0f); + callback.onSearchEntered(s.toString()); + } + + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + } + + @Override + public void afterTextChanged(Editable s) { + } + }); + searchView.setOnEditorActionListener(new TextView.OnEditorActionListener() { + @Override + public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { + if (actionId == EditorInfo.IME_ACTION_DONE) { + AndroidUtils.hideKeyboard(searchView); + callback.onSearchEntered(searchView.getText().toString()); + return true; + } + return false; + } + }); + LinearLayout.LayoutParams searchViewParams = new LinearLayout.LayoutParams(0, dp(36), 1); + searchViewParams.gravity = Gravity.CENTER_VERTICAL; + addView(searchView, searchViewParams); + + clearButton.setAlpha(0.6f); + clearButton.setImageResource(R.drawable.ic_clear_white_24dp); + clearButton.setScaleType(ImageView.ScaleType.CENTER); + clearButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + searchView.setText(""); + AndroidUtils.requestKeyboardFocus(searchView); + } + }); + addView(clearButton, dp(48), LayoutParams.MATCH_PARENT); + } + + public void setHintColor(int color) { + searchView.setHintTextColor(color); + } + + public void setTextColor(int color) { + searchView.setTextColor(color); + } + + public void setClearButtonImage(int image) { + clearButton.setImageResource(image); + } + + public void setText(String text) { + searchView.setText(text); + } + + public void setHint(String hint) { + searchView.setHint(hint); + } + + public void openKeyboard() { + searchView.postDelayed(new Runnable() { + @Override + public void run() { + searchView.requestFocus(); + AndroidUtils.requestKeyboardFocus(searchView); + } + }, 100); + } + + public interface SearchLayoutCallback { + void onSearchEntered(String entered); + } +} diff --git a/Clover/app/src/main/java/org/floens/chan/ui/toolbar/Toolbar.java b/Clover/app/src/main/java/org/floens/chan/ui/toolbar/Toolbar.java index 9bf27ab1..eeafd25e 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/toolbar/Toolbar.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/toolbar/Toolbar.java @@ -26,19 +26,13 @@ import android.annotation.SuppressLint; import android.content.Context; import android.graphics.drawable.Drawable; import android.os.Build; -import android.text.Editable; import android.text.TextUtils; -import android.text.TextWatcher; import android.util.AttributeSet; -import android.util.TypedValue; import android.view.Gravity; -import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.animation.DecelerateInterpolator; -import android.view.inputmethod.EditorInfo; -import android.widget.EditText; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.LinearLayout; @@ -47,6 +41,7 @@ import android.widget.TextView; import org.floens.chan.R; import org.floens.chan.ui.drawable.ArrowMenuDrawable; import org.floens.chan.ui.drawable.DropdownArrowDrawable; +import org.floens.chan.ui.layout.SearchLayout; import org.floens.chan.ui.view.LoadView; import org.floens.chan.utils.AndroidUtils; @@ -286,76 +281,30 @@ public class Toolbar extends LinearLayout implements View.OnClickListener, LoadV private LinearLayout createNavigationItemView(final NavigationItem item) { if (item.search) { - LinearLayout searchViewWrapper = new LinearLayout(getContext()); - final EditText searchView = new EditText(getContext()); - searchView.setImeOptions(EditorInfo.IME_FLAG_NO_FULLSCREEN | EditorInfo.IME_ACTION_DONE); - searchView.setHint(callback.getSearchHint()); - if (item.searchText != null) { - searchView.setText(item.searchText); - } - searchView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18); - searchView.setHintTextColor(0x88ffffff); - searchView.setTextColor(0xffffffff); - searchView.setSingleLine(true); - searchView.setBackgroundResource(0); - searchView.setPadding(0, 0, 0, 0); - final ImageView clearButton = new ImageView(getContext()); - searchView.addTextChangedListener(new TextWatcher() { - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) { - item.searchText = s.toString(); - callback.onSearchEntered(s.toString()); - clearButton.setAlpha(s.length() == 0 ? 0.6f : 1.0f); - } + SearchLayout searchLayout = new SearchLayout(getContext()); + searchLayout.setCallback(new SearchLayout.SearchLayoutCallback() { @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) { - } - - @Override - public void afterTextChanged(Editable s) { - } - }); - searchView.setOnEditorActionListener(new TextView.OnEditorActionListener() { - @Override - public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { - if (actionId == EditorInfo.IME_ACTION_DONE) { - AndroidUtils.hideKeyboard(searchView); - callback.onSearchEntered(searchView.getText().toString()); - return true; - } - return false; - } - }); - LinearLayout.LayoutParams searchViewParams = new LinearLayout.LayoutParams(0, dp(36), 1); - searchViewParams.gravity = Gravity.CENTER_VERTICAL; - searchViewWrapper.addView(searchView, searchViewParams); - - clearButton.setImageResource(R.drawable.ic_clear_white_24dp); - clearButton.setAlpha(searchView.length() == 0 ? 0.6f : 1.0f); - clearButton.setScaleType(ImageView.ScaleType.CENTER); - clearButton.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - searchView.setText(""); - AndroidUtils.requestKeyboardFocus(searchView); + public void onSearchEntered(String entered) { + item.searchText = entered; + callback.onSearchEntered(entered); } }); - searchViewWrapper.addView(clearButton, dp(48), LayoutParams.MATCH_PARENT); - searchViewWrapper.setPadding(dp(16), 0, 0, 0); + + if (item.searchText != null) { + searchLayout.setText(item.searchText); + } + + searchLayout.setHint(callback.getSearchHint()); if (openKeyboardAfterSearchViewCreated) { openKeyboardAfterSearchViewCreated = false; - searchView.postDelayed(new Runnable() { - @Override - public void run() { - searchView.requestFocus(); - AndroidUtils.requestKeyboardFocus(searchView); - } - }, 100); + searchLayout.openKeyboard(); } - return searchViewWrapper; + searchLayout.setPadding(dp(16), searchLayout.getPaddingTop(), searchLayout.getPaddingRight(), searchLayout.getPaddingBottom()); + + return searchLayout; } else { @SuppressLint("InflateParams") LinearLayout menu = (LinearLayout) LayoutInflater.from(getContext()).inflate(R.layout.toolbar_menu, null); diff --git a/Clover/app/src/main/res/layout/cell_board_select.xml b/Clover/app/src/main/res/layout/cell_board_select.xml new file mode 100644 index 00000000..d80f3e80 --- /dev/null +++ b/Clover/app/src/main/res/layout/cell_board_select.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + diff --git a/Clover/app/src/main/res/layout/layout_board_select.xml b/Clover/app/src/main/res/layout/layout_board_select.xml new file mode 100644 index 00000000..3eaa698c --- /dev/null +++ b/Clover/app/src/main/res/layout/layout_board_select.xml @@ -0,0 +1,54 @@ + + + + + + + +