#pragma once #include #if 1 #include #else #include #endif #include "control/ZKListView.h" #include "entry/EasyUIContext.h" #include "utils/Log.h" struct TextExtent { int w; int h; }; TextExtent GetTextExtent(ZKTextView* view, const std::string& str); std::string EllipsisText(ZKTextView* view, const std::string& str); class Field : protected IMEContext::IIMETextUpdateListener{ public: typedef std::map ItemMap; enum Names { ICON = 100, ONLY_TITLE, TITLE, VALUE, ARRAW, SWITCH, DIVIDER, PRIMARY_BUTTON, }; typedef std::function TextGetter; typedef std::function SwitchGetter; friend class Form; Field() { arraw_ = true; switch_ = false; divider_ = true; } virtual ~Field() {} Field& Title(const char* title) { title_ = title; return self(); } Field& Title(const TextGetter& title_get) { title_get_ = title_get; return self(); } Field& Icon(const std::string& icon) { icon_ = icon; return self(); } Field& Arraw(bool arraw) { arraw_ = arraw; if (arraw) { switch_ = false; } return self(); } Field& Divider(bool divider) { divider_ = divider; return self(); } Field& Switch(const SwitchGetter& get) { switch_ = true; arraw_ = false; switch_get_ = get; return self(); } Field& Text(const TextGetter& get) { get_ = get; return self(); } std::string Text() { if (get_ == NULL) { return ""; } return get_(this); } typedef std::function ClickCallback; Field& Click(const ClickCallback& callback) { click_callback_ = callback; return self(); } typedef std::function EditCallback; Field& Edit(const EditCallback& callback) { edit_callback_ = callback; return self(); } protected: Field& self() { return *dynamic_cast(this); } void Click() { if (click_callback_ != NULL) { click_callback_(&self()); return; } if (edit_callback_ != NULL) { #if 1 ime_info.text = get_ == NULL ? "" : get_(this); #else ime_info.text = ""; #endif ime_info.isPassword = false; ime_info.imeTextType = IMEContext::E_IME_TEXT_TYPE_ALL; EASYUICONTEXT->showIME(&ime_info, this); } } virtual void onIMETextUpdate(const std::string &text) { if (edit_callback_ == NULL) { return; } edit_callback_(this, text); } virtual void Paint(ZKListView* list_view, ZKListView::ZKListItem *item, int index, ItemMap& item_map) { if (item_map[ICON] == nullptr) { LOGE("ICON item must not be null"); return; } if (item_map[TITLE] == nullptr) { LOGE("TITLE item must not be null"); return; } if (item_map[ONLY_TITLE] == nullptr) { LOGE("ONLY_TITLE item must not be null"); return; } if (item_map[VALUE] == nullptr) { LOGE("VALUE item must not be null"); return; } if (item_map[ARRAW] == nullptr) { LOGE("ARRAW item must not be null"); return; } if (item_map[SWITCH] == nullptr) { LOGE("SWITCH item must not be null"); return; } item_map[ICON]->setBackgroundPic(icon_.c_str()); std::string title_str = title_; if (title_get_ != NULL) { title_str = title_get_(this); } item_map[ONLY_TITLE]->setText(icon_.empty() ? title_str : ""); item_map[TITLE]->setText( EllipsisText(item_map[TITLE], icon_.empty() ? "" : title_str)); std::string str = get_ == NULL ? "" : get_(this); if (arraw_ & !str.empty()) { str += " ";//箭头和文字同时存在,需要为箭头空出距离 } item_map[VALUE]->setText(EllipsisText(item_map[VALUE], str)); item_map[ARRAW]->setBackgroundPic(arraw_ ? "ic_arraw_right.png" : ""); bool is_on = switch_get_ == NULL ? false : switch_get_(this); item_map[SWITCH]->setBackgroundPic(switch_ ? (is_on ? "settings/on_2.png" : "settings/off_2.png") : ""); if (item_map[DIVIDER] != nullptr) { item_map[DIVIDER]->setAlpha( (divider_ && (index != list_view->getListItemCount() -1)) ? 0 : 255); // item_map[DIVIDER]->setBackgroundColor( // (divider_ && (index != list_view->getListItemCount() -1)) // ? 0xff2E3035 : 0); } } protected: std::string icon_; std::string title_; bool arraw_; bool divider_; bool switch_; ClickCallback click_callback_; EditCallback edit_callback_; IMEContext::SIMETextInfo ime_info; TextGetter get_; TextGetter title_get_; SwitchGetter switch_get_; friend class UIForm; }; class FieldFactory { public: static Field& Text() { Field* field = new Field(); return *field; } static Field& Placeholder() { Field* field = new Field(); field->Arraw(false); field->Divider(false); return *field; } static Field& Text(const std::string& title) { Field* field = new Field(); field->Title(title.c_str()); return *field; } };