Skip to content
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 30 additions & 1 deletion flutter/shell/platform/tizen/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -174,15 +174,44 @@ template("embedder") {
defines += invoker.defines
defines += [ "FLUTTER_ENGINE_NO_PROTOTYPES" ]

if (api_version == "6.5" && target_name != "flutter_tizen_wearable") {
if (api_version == "5.5") {
major_version = 5
minor_version = 5
} else if (api_version == "6.0") {
major_version = 6
minor_version = 0
} else if (api_version == "6.5") {
major_version = 6
minor_version = 5
} else if (api_version == "7.0") {
major_version = 7
minor_version = 0
}

if (((major_version >= 5 && minor_version >= 5) || major_version >= 6) &&
target_name != "flutter_tizen_wearable") {
sources += [ "tizen_autofill.cc" ]

libs += [
"capi-ui-autofill",
"capi-ui-autofill-common",
]

defines += [ "AUTOFILL_SUPPORT" ]
}

if (((major_version >= 6 && minor_version >= 5) || major_version >= 7) &&
target_name != "flutter_tizen_wearable") {
sources += [
"flutter_tizen_nui.cc",
"nui_autofill_popup.cc",
"tizen_view_nui.cc",
]

libs += [
"dali2-adaptor",
"dali2-core",
"dali2-toolkit",
]

defines += [ "NUI_SUPPORT" ]
Expand Down
53 changes: 53 additions & 0 deletions flutter/shell/platform/tizen/channels/text_input_channel.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
#include "flutter/shell/platform/tizen/flutter_tizen_engine.h"
#include "flutter/shell/platform/tizen/logger.h"

#ifdef AUTOFILL_SUPPORT
#include "flutter/shell/platform/tizen/tizen_autofill.h"
#endif

namespace flutter {

namespace {
Expand All @@ -23,8 +27,10 @@ constexpr char kMultilineInputType[] = "TextInputType.multiline";
constexpr char kUpdateEditingStateMethod[] =
"TextInputClient.updateEditingState";
constexpr char kPerformActionMethod[] = "TextInputClient.performAction";
constexpr char kRequestAutofillMethod[] = "TextInput.requestAutofill";
constexpr char kSetPlatformViewClient[] = "TextInput.setPlatformViewClient";
constexpr char kTextCapitalization[] = "textCapitalization";
constexpr char kTextEnableSuggestions[] = "enableSuggestions";
constexpr char kTextInputAction[] = "inputAction";
constexpr char kTextInputType[] = "inputType";
constexpr char kTextInputTypeName[] = "name";
Expand All @@ -40,6 +46,9 @@ constexpr char kSelectionIsDirectionalKey[] = "selectionIsDirectional";
constexpr char kTextKey[] = "text";
constexpr char kBadArgumentError[] = "Bad Arguments";
constexpr char kInternalConsistencyError[] = "Internal Consistency Error";
constexpr char kAutofill[] = "autofill";
constexpr char kUniqueIdentifier[] = "uniqueIdentifier";
constexpr char kHints[] = "hints";

bool IsAsciiPrintableKey(char ch) {
return ch >= 32 && ch <= 126;
Expand All @@ -60,6 +69,12 @@ TextInputChannel::TextInputChannel(
std::unique_ptr<MethodResult<rapidjson::Document>> result) {
HandleMethodCall(call, std::move(result));
});
#ifdef AUTOFILL_SUPPORT
TizenAutofill& instance = TizenAutofill::GetInstance();
Comment thread
swift-kim marked this conversation as resolved.
Outdated
instance.SetPopupCallback(
[this]() { input_method_context_->PopupAutofillItems(); });
instance.SetCommitCallback([this](std::string value) { OnCommit(value); });
#endif
}

TextInputChannel::~TextInputChannel() {}
Expand Down Expand Up @@ -162,11 +177,21 @@ void TextInputChannel::HandleMethodCall(
}

client_id_ = client_id_json.GetInt();

auto enable_suggestions_iter =
client_config.FindMember(kTextEnableSuggestions);
if (enable_suggestions_iter != client_config.MemberEnd() &&
enable_suggestions_iter->value.IsBool()) {
bool enable = enable_suggestions_iter->value.GetBool();
input_method_context_->SetEnableSuggestions(enable);
}

input_action_ = "";
auto input_action_iter = client_config.FindMember(kTextInputAction);
if (input_action_iter != client_config.MemberEnd() &&
input_action_iter->value.IsString()) {
input_action_ = input_action_iter->value.GetString();
input_method_context_->SetInputAction(input_action_);
}

text_capitalization_ = "";
Expand Down Expand Up @@ -211,6 +236,27 @@ void TextInputChannel::HandleMethodCall(
}
}

auto autofill_iter = client_config.FindMember(kAutofill);
if (autofill_iter != client_config.MemberEnd() &&
autofill_iter->value.IsObject()) {
auto unique_identifier_iter =
autofill_iter->value.FindMember(kUniqueIdentifier);
if (unique_identifier_iter != autofill_iter->value.MemberEnd() &&
unique_identifier_iter->value.IsString()) {
autofill_id_ = unique_identifier_iter->value.GetString();
}

auto hints_iter = autofill_iter->value.FindMember(kHints);
if (hints_iter != autofill_iter->value.MemberEnd() &&
hints_iter->value.IsArray()) {
for (auto hint = hints_iter->value.GetArray().Begin();
hint != hints_iter->value.GetArray().End(); hint++) {
autofill_hints_.clear();
Comment thread
swift-kim marked this conversation as resolved.
Outdated
autofill_hints_.push_back(hint->GetString());
}
}
}

active_model_ = std::make_unique<TextInputModel>();
} else if (method.compare(kSetEditingStateMethod) == 0) {
input_method_context_->ResetInputMethodContext();
Expand Down Expand Up @@ -273,6 +319,13 @@ void TextInputChannel::HandleMethodCall(
cursor_offset);
}
SendStateUpdate();
} else if (method.compare(kRequestAutofillMethod) == 0) {
#ifdef AUTOFILL_SUPPORT
TizenAutofill& instance = TizenAutofill::GetInstance();
instance.RequestAutofill(autofill_hints_, autofill_id_);
#else
result->NotImplemented();
#endif
} else {
result->NotImplemented();
return;
Expand Down
5 changes: 5 additions & 0 deletions flutter/shell/platform/tizen/channels/text_input_channel.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include <memory>
#include <string>
#include <vector>

#include "flutter/shell/platform/common/client_wrapper/include/flutter/binary_messenger.h"
#include "flutter/shell/platform/common/client_wrapper/include/flutter/method_channel.h"
Expand Down Expand Up @@ -79,6 +80,10 @@ class TextInputChannel {
// Automatic text capitalization type. See available options:
// https://api.flutter.dev/flutter/services/TextCapitalization.html
std::string text_capitalization_ = "";

std::string autofill_id_;
Comment thread
swift-kim marked this conversation as resolved.

std::vector<std::string> autofill_hints_;
};

} // namespace flutter
Expand Down
82 changes: 82 additions & 0 deletions flutter/shell/platform/tizen/nui_autofill_popup.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// Copyright 2023 Samsung Electronics Co., Ltd. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "flutter/shell/platform/tizen/nui_autofill_popup.h"

#include <dali-toolkit/dali-toolkit.h>
#include <dali-toolkit/devel-api/controls/table-view/table-view.h>
#include <dali-toolkit/public-api/controls/text-controls/text-label.h>

#include "flutter/shell/platform/tizen/tizen_autofill.h"

namespace flutter {
Comment thread
swift-kim marked this conversation as resolved.
bool NuiAutofillPopup::OnTouch(Dali::Actor actor,
const Dali::TouchEvent& event) {
const Dali::PointState::Type state = event.GetState(0);
if (Dali::PointState::DOWN == state) {
auto t = actor.GetProperty(Dali::Actor::Property::NAME).Get<std::string>();
Comment thread
swift-kim marked this conversation as resolved.
Outdated
on_commit_(t);
OnHide();
Comment thread
swift-kim marked this conversation as resolved.
Outdated
}
return true;
}

void NuiAutofillPopup::OnHide() {
Comment thread
bbrto21 marked this conversation as resolved.
Outdated
// TODO : There is a phenomenon where white traces remain for a while when
Comment thread
swift-kim marked this conversation as resolved.
Outdated
// popup disappears.
popup_.SetDisplayState(Dali::Toolkit::Popup::HIDDEN);
}

void NuiAutofillPopup::OnHidden() {
popup_.Unparent();
popup_.Reset();
}

void NuiAutofillPopup::PrepareAutofill() {
popup_ = Dali::Toolkit::Popup::New();
popup_.SetProperty(Dali::Actor::Property::NAME, "popup");
popup_.SetProperty(Dali::Actor::Property::PARENT_ORIGIN,
Dali::ParentOrigin::TOP_LEFT);
popup_.SetProperty(Dali::Actor::Property::ANCHOR_POINT,
Dali::AnchorPoint::TOP_LEFT);
popup_.SetProperty(Dali::Toolkit::Popup::Property::TAIL_VISIBILITY, false);
popup_.SetBackgroundColor(Dali::Color::WHITE_SMOKE);
popup_.OutsideTouchedSignal().Connect(this, &NuiAutofillPopup::OnHide);
popup_.HiddenSignal().Connect(this, &NuiAutofillPopup::OnHidden);
popup_.SetProperty(Dali::Toolkit::Popup::Property::BACKING_ENABLED, false);
popup_.SetProperty(Dali::Toolkit::Popup::Property::AUTO_HIDE_DELAY, 2500);
Comment thread
JSUYA marked this conversation as resolved.
}

void NuiAutofillPopup::PopupAutofill(Dali::Actor* actor) {
Comment thread
swift-kim marked this conversation as resolved.
Outdated
const auto& items = TizenAutofill::GetInstance().GetAutofillItems();
if (items.size() > 0) {
Comment thread
swift-kim marked this conversation as resolved.
Outdated
PrepareAutofill();
Dali::Toolkit::TableView content =
Dali::Toolkit::TableView::New(items.size(), 1);
// content.SetCellPadding(Dali::Size(10.0f, 0));
Comment thread
JSUYA marked this conversation as resolved.
Outdated
content.SetResizePolicy(Dali::ResizePolicy::FILL_TO_PARENT,
Dali::Dimension::ALL_DIMENSIONS);
content.SetProperty(Dali::Actor::Property::PADDING,
Dali::Vector4(10, 10, 0, 0));
for (uint32_t i = 0; i < items.size(); ++i) {
auto label = Dali::Toolkit::TextLabel::New(items[i]->label_);
label.SetProperty(Dali::Actor::Property::NAME, items[i]->value_);
label.SetResizePolicy(Dali::ResizePolicy::DIMENSION_DEPENDENCY,
Dali::Dimension::HEIGHT);
label.SetProperty(Dali::Toolkit::TextLabel::Property::TEXT_COLOR,
Dali::Color::WHITE_SMOKE);
label.SetProperty(Dali::Toolkit::TextLabel::Property::POINT_SIZE, 7.0f);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Q. Are there any default values for these properties? It'd be nice if we could avoid using magic numbers.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default text color is black and the point size is about 15.
The background color of the pop-up window is dark blue, so I can't see the letters well, so I set it to white smoke.
The font size is set to an appropriate size because the default value is large, but we will modify it so that we do not use the magic number.
However, if we do not change the background color of popup, white smoke will be better than the basic color(black).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does "white background" and "7.0f font size" look good for both tv and common (rpi) profiles?

+) NUI popup may differ from Dali popup. It might be better to set it equal to that value.
https://docs.tizen.org/application/dotnet/guides/user-interface/nui/nui-components/Popup/

label.TouchedSignal().Connect(this, &NuiAutofillPopup::OnTouch);
content.AddChild(label, Dali::Toolkit::TableView::CellPosition(i, 0));
content.SetFitHeight(i);
}
popup_.SetProperty(Dali::Actor::Property::SIZE,
Dali::Vector2(140.0f, 35.0f * items.size()));
Comment thread
JSUYA marked this conversation as resolved.
Outdated
popup_.SetContent(content);
popup_.SetDisplayState(Dali::Toolkit::Popup::SHOWN);
actor->Add(popup_);
}
}

} // namespace flutter
38 changes: 38 additions & 0 deletions flutter/shell/platform/tizen/nui_autofill_popup.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright 2023 Samsung Electronics Co., Ltd. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef EMBEDDER_NUI_AUTOFILL_POPUP_H_
#define EMBEDDER_NUI_AUTOFILL_POPUP_H_

#include <dali-toolkit/devel-api/controls/popup/popup.h>

#include <functional>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing includes?

#include <dali/public-api/dali-core.h>

#include <string>

Please consult me or @bbrto21 on how to organize includes in the implementation file (nui_autofill_popup.cc) in a consistent way.


namespace flutter {

using OnCommit = std::function<void(std::string str)>;
Comment thread
swift-kim marked this conversation as resolved.
Outdated
using OnRendering = std::function<void()>;
Comment thread
swift-kim marked this conversation as resolved.
Outdated

class NuiAutofillPopup : public Dali::ConnectionTracker {
Comment thread
swift-kim marked this conversation as resolved.
public:
bool OnTouch(Dali::Actor actor, const Dali::TouchEvent& event);

void OnHide();

void OnHidden();

void PrepareAutofill();

void PopupAutofill(Dali::Actor* actor);

void SetOnCommit(OnCommit callback) { on_commit_ = callback; }

private:
Dali::Toolkit::Popup popup_;
OnCommit on_commit_;
};

} // namespace flutter

#endif
Loading