rect { "bg";
scale;
mouse;
- repeat;
desc { "default";
min: CU_ACCEPT_REJECT_ICON_BG_SIZE;
fixed: 1 1;
// Control parts
- swallow { "swl.accept.finger.event";
- scale;
- mouse;
- desc { "default";
- min: CU_ACCEPT_REJECT_ICON_BG_SIZE;
- fixed: 1 1;
- rel1 { relative: CU_ACCEPT_COMPONENT_REL; to: "bg"; }
- rel2 { relative: CU_ACCEPT_COMPONENT_REL; to: "bg"; }
- }
- }
swallow { "swl.accept.finger.guide.bg";
scale;
- mouse;
- repeat;
desc { "default";
min: CU_ACCEPT_REJECT_ICON_BG_SIZE;
fixed: 1 1;
}
swallow { "swl.accept.finger.tracer";
scale;
- mouse;
- repeat;
desc { "default";
min: CU_ACCEPT_REJECT_FINGER_TRACER_BG_SIZE;
fixed: 1 1;
}
swallow { "swl.accept.icon";
scale;
- mouse;
- repeat;
desc { "default";
min: CU_ACCEPT_REJECT_ICON_SIZE;
fixed: 1 1;
rel2 { relative: CU_ACCEPT_COMPONENT_REL; to: "bg"; }
}
}
- swallow { "swl.reject.finger.event";
+ swallow { "swl.accept.finger.event";
scale;
mouse;
desc { "default";
min: CU_ACCEPT_REJECT_ICON_BG_SIZE;
fixed: 1 1;
- rel1 { relative: CU_REJECT_COMPONENT_REL; to: "bg"; }
- rel2 { relative: CU_REJECT_COMPONENT_REL; to: "bg"; }
+ rel1 { relative: CU_ACCEPT_COMPONENT_REL; to: "bg"; }
+ rel2 { relative: CU_ACCEPT_COMPONENT_REL; to: "bg"; }
}
}
swallow { "swl.reject.finger.guide.bg";
scale;
- mouse;
- repeat;
desc { "default";
min: CU_ACCEPT_REJECT_ICON_BG_SIZE;
fixed: 1 1;
}
swallow { "swl.reject.finger.tracer";
scale;
- mouse;
- repeat;
desc { "default";
min: CU_ACCEPT_REJECT_FINGER_TRACER_BG_SIZE;
fixed: 1 1;
}
swallow { "swl.reject.icon";
scale;
- mouse;
- repeat;
desc { "default";
min: CU_ACCEPT_REJECT_ICON_SIZE;
fixed: 1 1;
rel2 { relative: CU_REJECT_COMPONENT_REL; to: "bg"; }
}
}
+ swallow { "swl.reject.finger.event";
+ scale;
+ mouse;
+ desc { "default";
+ min: CU_ACCEPT_REJECT_ICON_BG_SIZE;
+ fixed: 1 1;
+ rel1 { relative: CU_REJECT_COMPONENT_REL; to: "bg"; }
+ rel2 { relative: CU_REJECT_COMPONENT_REL; to: "bg"; }
+ }
+ }
}
}
CU_DOT("dot.first", 3, -3)
CU_DOT("dot.second", 9, -9)
CU_DOT("dot.third", 15, -15)
+
rect { "ao_text_info";
mouse;
scale;
desc { "default";
- rel1.to: "text_info";
- rel2.to: "text_info";
+ fixed: 1 1;
+ align: 0.0 0.0;
+ min: 208 32;
+ max: 208 32;
+ rel1 { relative: 1.0 1.0; to_x: "left.pad"; to_y: "top.pad"; }
+ rel2 { relative: 0.0 1.0; to_x: "right.pad"; to_y: "top.pad"; }
color: 0 0 0 0;
}
}
}
}
}
+
+group { "elm/layout/callui/fake_access_object";
+ data.item: "access_highlight" "on";
+}
text.fit: 1 1;
}
}
+ rect { "ao_txt.status";
+ mouse;
+ scale;
+ desc { "default";
+ rel1.to: "txt.status";
+ rel2.to: "txt.status";
+ color: 0 0 0 0;
+ }
+ }
swallow { "swl.slot.1";
scale;
desc { "default";
}
}
image { "cue";
- repeat;
+ scale;
desc { "default";
align: 0.5 1.0;
fixed: 0 1;
}
textblock { "reject_msg_text";
scale;
- nomouse;
- repeat;
desc { "default";
rel1 { relative: 0.0 0.0; to: "reject_msg_text_zone"; }
rel2 { relative: 1.0 1.0; to: "reject_msg_text_zone"; }
hid;
}
}
+ rect { "ao_cue";
+ mouse;
+ scale;
+ desc { "default";
+ rel1 { relative: 0.0 0.0; to: "reject_msg_text_zone"; }
+ rel2 { relative: 1.0 1.0; to_x: "reject_msg_text_zone"; }
+ color: 0 0 0 0;
+ }
+ }
}
}
hid;
}
}
+ textblock { "ao_txt.value";
+ scale;
+ mouse;
+ desc { "default";
+ fixed: 1 1;
+ rel1.to: "txt.value";
+ rel2.to: "txt.value";
+ }
+ desc { "hide";
+ hid;
+ }
+ }
swallow { "swl.minus";
scale;
desc { "default";
namespace callui {
+ constexpr auto PACKAGE = "w-call-ui";
+
constexpr auto WINDOW_NAME = "org.tizen.call-ui";
constexpr auto BASE_SCALE = 1.3;
}
-#endif // __CALL_UI_CONFIG_H__
+#endif // __CALLUI_CONFIG_H__
void update(CallMask calls);
+ ucl::ElmWidget *getAcceptAo();
+ ucl::ElmWidget *getRejectAo();
+
private:
friend class ucl::ReffedObj<AcceptRejectPresenter>;
AcceptRejectPresenter(ucl::IRefCountObj &rc,
void hideVolumeControls();
ucl::Result update(const ICallManagerSRef &cm);
+ // Screen Reader
+ ucl::ElmWidget *getVolumBtn();
+ ucl::ElmWidget *getBluetoothBtn();
+ ucl::ElmWidget *getMuteBtn();
+ ucl::ElmWidget *getAddContactBtn();
+ ucl::ElmWidget *getVolumeControlLy();
+ ucl::ElmWidget *getVolumeControlDecreaseBtn();
+ ucl::ElmWidget *getVolumeControlIncreaseBtn();
+ ucl::ElmWidget *getVolumeControlValueTxtAo();
+
private:
enum class ComponentsMode {
UNDEFINED,
void onVolumeControlEventCb(VolumeControlEvent event);
Eina_Bool onRotaryEvent(Eext_Rotary_Event_Info *info);
+ bool checkPossibilityToModifyVolume(int volume,
+ bool needIncrease);
void tryIncreaseVolume();
void tryDecreaseVolume();
ucl::Result setActiveCallCompomnents();
ucl::Result setEndCallCompomnents(const ICallManagerSRef &cm);
+ // Screen Reader
+ void registerVolumeControlAo();
+ void onVolumeControlScreenReaderReadStart(ucl::Widget &widget, void *eventInfo);
+
private:
ucl::LayoutSRef m_widget;
ucl::StyledWidgetSRef m_volumeBtn;
ComponentsMode m_mode;
std::string m_unsavedPhoneNumber;
NotiHandler m_exitHandler;
+
+ bool m_isVcShowOnRotaryEvent;
};
}
-
-
#endif // __CALLUI_PRESENTERS_ACCESSORY_PRESENTER_H__
--- /dev/null
+/*
+ * Copyright 2017 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * 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.
+ */
+
+#ifndef __CALLUI_PRESENTERS_ATSPI_HIGHLIGHT_HELPER_H__
+#define __CALLUI_PRESENTERS_ATSPI_HIGHLIGHT_HELPER_H__
+
+#include "ucl/mvp/GuiPresenter.h"
+
+#include "types.h"
+
+namespace callui {
+
+ class AtspiHighlightHelper final : public ucl::GuiPresenter {
+ public:
+ using RelationEventHandler = ucl::WeakDelegate<Elm_Interface_Atspi_Accessible *(
+ Elm_Interface_Atspi_Accessible *ao,
+ Elm_Atspi_Relation_Type flowRelation)>;
+
+ using GestureEventHandler = ucl::WeakDelegate<bool (
+ Elm_Interface_Atspi_Accessible *ao,
+ Elm_Atspi_Gesture_Type gestureType)>;
+ public:
+ static AtspiHighlightHelperSRef newInstance(GuiPresenter &parent,
+ ucl::ElmWidget &rootWidget);
+
+ void setRelationEventHandler(RelationEventHandler handler);
+ void setGestureEventHandler(GestureEventHandler handler);
+ void registerWidget(ucl::ElmWidget &widget);
+ bool handleGesture(Elm_Interface_Atspi_Accessible *widget,
+ const Elm_Atspi_Gesture_Info &info);
+
+ private:
+ friend class ucl::ReffedObj<AtspiHighlightHelper>;
+ AtspiHighlightHelper(ucl::IRefCountObj &rc);
+ virtual ~AtspiHighlightHelper();
+
+ ucl::Result prepare(GuiPresenter &parent, ucl::ElmWidget &rootWidget);
+
+ void handleAtspiGesture(Elm_Interface_Atspi_Accessible *widget,
+ ucl::AtspiGestureEventInfo &e);
+
+ private:
+ void onAtspiGesture(ucl::Widget &widget, void *eventInfo);
+
+ private:
+ RelationEventHandler m_relationEventHandler;
+ GestureEventHandler m_gestureEventHandler;
+ };
+}
+
+#endif // __CALLUI_PRESENTERS_ATSPI_HIGHLIGHT_HELPER_H__
CallMode getMode() const;
ucl::Result update(CallMode mode, const ICallManagerSRef &cm);
+ // Screen Reader
+ ucl::ElmWidget *getStatusTxtAo();
+ ucl::ElmWidget *getMainTxtAo();
+ ucl::ElmWidget *getSubTxtAo();
+
private:
friend class ucl::ReffedObj<CallInfoPresenter>;
CallInfoPresenter(ucl::IRefCountObj &rc,
ucl::Result updateCallerId();
ucl::Result updateSubText();
ucl::Result updateMainTxt();
-
std::string getNumberSubText(const ICallInfoSCRef &callInfo) const;
std::string getIncomingCallSubText() const;
std::string getOutgoingCallSubText() const;
std::string generateMainTxt(const ICallInfoSCRef &callInfo);
- void displayMainTxt(const ICallInfoSCRef &info, const std::string &text) const;
+ void displayMainTxt(const ICallInfoSCRef &info, const std::string &text);
+
+ // Screen Reader
+ ucl::Result setMainTxtAccessObject(const std::string &text);
+ ucl::Result setSubTxtAccessObject(const std::string &text);
+
private:
ucl::LayoutSRef m_widget;
ucl::StyledWidgetSRef m_callerId;
CallStatusPresenterSRef m_callStatus;
bool m_isSubTxtEnable;
bool m_needModifyCallStatus;
+
+ // Screen Reader
+ ucl::ElmWidgetSRef m_statusAO;
+ ucl::ElmWidgetSRef m_mainTxtAO;
+ ucl::ElmWidgetSRef m_subTxtAO;
};
}
public:
virtual ~CallStatusPresenter();
+ // Screen Reader
+ ucl::ElmWidget *getStatusTextAo();
+
private:
friend class ucl::ReffedObj<CallStatusPresenter>;
CallStatusPresenter(ucl::IRefCountObj &rc,
Eina_Bool onCallDurationTimerCb();
Eina_Bool onBlinkingTimerCb();
+ // Screen Reader
+ ucl::Result createStatusTxtAo();
+
private:
ucl::LayoutSRef m_ly;
CallMode m_mode;
Ecore_Timer *m_timer;
struct tm m_duration;
int m_blinkCount;
+
+ // Screen Reader
+ ucl::ElmWidgetSRef m_statusTxtAo;
};
}
ucl::Result createRejectMsgPresenter(
const IRejectMsgProviderSRef &provider);
+ ucl::Result createRejectMsgCue();
void RejectMsgStateCb(RejectMsgState state);
void RejectMsgSelectCb(const IRejectMsgSRef &rm);
- ucl::Result createBottomBtn(const ucl::ElmStyle &style);
+ ucl::Result createBottomBtn(const ucl::ElmStyle &style,
+ bool setVisible = true);
void onBottomBtnClicked(ucl::Widget &widget, void *eventInfo);
void startEndCallTimer();
void onPowerKeyUp(ucl::Widget &widget, void *eventInfo);
void processKeyPress();
- bool detectMuteControlDisableState();
-
ucl::Result updateDeviceState(CallMode prevMode, CallMode curMode);
ucl::Result createWidget();
void onExitAppRequest();
+ // Screen Reader
+ ucl::Result createRejectMsgCueAo();
+ ucl::Result createAtspiHighlightHelper();
+ void registerIncomingCallModeAo();
+ void registerActiveCallModeAo();
+ void registerEndCallModeAo();
+ Elm_Interface_Atspi_Accessible *onIncomingCallModeAtspiHighlight(
+ Elm_Interface_Atspi_Accessible *widget,
+ Elm_Atspi_Relation_Type flowRelation);
+ Elm_Interface_Atspi_Accessible *onActiveCallModeAtspiHighlight(
+ Elm_Interface_Atspi_Accessible *widget,
+ Elm_Atspi_Relation_Type flowRelation);
+ Elm_Interface_Atspi_Accessible *onEndCallModeAtspiHighlight(
+ Elm_Interface_Atspi_Accessible *ao,
+ Elm_Atspi_Relation_Type flowRelation);
+ bool onIncomingModeAtspiGesture(
+ Elm_Interface_Atspi_Accessible *widget,
+ Elm_Atspi_Gesture_Type gestureType);
+
// Page
virtual void onBackKey() final override;
CallMode m_mode;
Ecore_Timer *m_ecTimer;
bool m_ecTimerBtnReq;
+
+ // Screen Reader
+ ucl::ElmWidgetSRef m_rmCueAo;
+ AtspiHighlightHelperSRef m_atspiHelper;
};
}
Builder &setNaviframe(const ucl::NaviframeSRef &navi);
Builder &setParentWidget(const ucl::ElmWidgetSRef &parentWidget);
MoreOptionsPresenterSRef build(ucl::GuiPresenter &parent) const;
+
private:
ICallManagerSRef m_cm;
ISoundManagerSRef m_sm;
ucl::Widget &getWidget();
void update();
+ // Screen Reader
+ ucl::ElmWidget *getCueAo();
+
private:
friend class ucl::ReffedObj<MoreOptionsPresenter>;
MoreOptionsPresenter(ucl::IRefCountObj &rc,
ucl::Result prepare(ucl::GuiPresenter &parent,
ucl::ElmWidget &parentWidget);
+ void updateComponents();
+
ucl::Result createWidget(ucl::ElmWidget &parent);
ucl::Result createPanel();
ucl::Result createPanelLayout();
- ucl::Result createButtons();
+
+ ucl::Result createSwapButton();
+ ucl::Result createUnholdButton();
+ ucl::Result createKeypadButton();
+
ucl::StyledWidgetSRef createButton(const ucl::ElmStyle &style,
const ucl::TString &txt,
const ucl::WidgetEventHandler &handler);
void onPanelInactivate(Evas_Object *obj,
const char *emission,
const char *source);
+ void onCueClicked(Evas_Object *obj,
+ const char *emission,
+ const char *source);
ucl::Result startCallDurationTimer();
void stopCallDurationTimer();
void onPageExitRequest(Page &page);
+ // Screen Reader
+ ucl::Result createAccessObjects();
+ ucl::Result createCueAo();
+ ucl::Result createStatusTxtAo();
+ ucl::Result createFakeAo();
+ ucl::Result createAtspiHighlightHelper();
+ Elm_Interface_Atspi_Accessible *onAtspiHighlight(
+ Elm_Interface_Atspi_Accessible *ao,
+ Elm_Atspi_Relation_Type flowRelation);
+ Eina_Bool onCueAoActionCb(Evas_Object *obj,
+ Elm_Access_Action_Info *actionInfo);
+
private:
ucl::LayoutSRef m_widget;
ucl::StyledWidgetSRef m_panel;
ucl::StyledWidgetSRef m_btnSwap;
ucl::StyledWidgetSRef m_btnUnhold;
ucl::StyledWidgetSRef m_btnKeypad;
- PageWRef m_keypad;
+ PageWRef m_keypad;
ICallManagerSRef m_cm;
ISoundManagerSRef m_sm;
ucl::NaviframeSRef m_navi;
-
ICallInfoWCRef m_info;
Ecore_Timer *m_timer;
struct tm m_duration;
+
+ // Screen Reader
+ AtspiHighlightHelperSRef m_atspiHelper;
+ ucl::ElmWidgetSRef m_fakeAo;
+ ucl::ElmWidgetSRef m_cueAo;
+ ucl::ElmWidgetSRef m_statusTxtAo;
};
}
RejectMsgState getState();
+ void showPanel();
void hidePanel();
void setStateHandler(const RejectMsgStateHandler &handler);
ucl::Result createPanelBg();
ucl::Result createPanelLy();
ucl::Result createGenlist();
- ucl::Result fillGenlist();
+ ucl::Result fillGenlist();
ucl::Result addGenlistTitleItem();
ucl::Result addGenlistTextItem(const IRejectMsgSRef &rm);
ucl::Result addGenlistBottomItem();
void onBackKey(Evas_Object *obj, void *eventInfo);
+ // Screen Reader
+ ucl::Result createAtspiHighlightHelper();
+ void registerGenlistAtspiGestureCallbacks();
+ Elm_Interface_Atspi_Accessible *getFirstAo();
+ Elm_Interface_Atspi_Accessible *getLastAo();
+ Eina_Bool onAtspiGesture(
+ Elm_Atspi_Gesture_Info gestureInfo,
+ Elm_Interface_Atspi_Accessible *ao);
+ Elm_Interface_Atspi_Accessible *onAtspiHighlight(
+ Elm_Interface_Atspi_Accessible *ao,
+ Elm_Atspi_Relation_Type flowRelation);
+
// Presenter
virtual void onActivate() final override;
RejectMsgSelectHandler m_selectHandler;
RejectMsgState m_state;
+ // Screen Reader
+ AtspiHighlightHelperSRef m_atspiHelper;
};
}
UCL_DECLARE_REF_ALIASES(DeviceStatePresenter);
UCL_DECLARE_REF_ALIASES(MotionSensorPresenter);
+ UCL_DECLARE_REF_ALIASES(AtspiHighlightHelper);
+
using AcceptDialogHandler = ucl::WeakDelegate<bool(AcceptDialog &, AcceptDialogEvent)>;
using RejectMsgStateHandler = ucl::WeakDelegate<void(RejectMsgState)>;
using RejectMsgSelectHandler = ucl::WeakDelegate<void(const IRejectMsgSRef &rm)>;
extern const ucl::TString STR_MORE_UNHOLD;
extern const ucl::TString STR_MORE_TRANSFER;
extern const ucl::TString STR_MORE_GEAR;
+
+ // Screen Reader
+ extern const ucl::TString AO_STR_CALL;
+ extern const ucl::TString AO_STR_VOLUME;
+ extern const ucl::TString AO_STR_HEADSET;
+ extern const ucl::TString AO_STR_GEAR_SPK;
+ extern const ucl::TString AO_STR_MUTE;
+ extern const ucl::TString AO_STR_MORE_OPTIONS;
+ extern const ucl::TString AO_STR_END_CALL;
+ extern const ucl::TString AO_STR_CALLBACK;
+ extern const ucl::TString AO_STR_ADD_TO_CONTACTS;
+ extern const ucl::TString AO_STR_ROTATE_BEZEL_TO_ADJUST;
+ extern const ucl::TString AO_STR_DECREASE_VOLUME;
+ extern const ucl::TString AO_STR_INCREASE_VOLUME;
+ extern const ucl::TString AO_STR_ACCEPT_CALL;
+ extern const ucl::TString AO_STR_SWIPE_RIGHT_WITH_TWO_FINGERS_TO_ACCEPT;
+ extern const ucl::TString AO_STR_REJECT_CALL;
+ extern const ucl::TString AO_STR_SWIPE_LEFT_WITH_TWO_FINGERS_TO_REJECT;
+ extern const ucl::TString AO_STR_DECLINE_MESSAGES;
+ extern const ucl::TString AO_STR_SWIPE_UP_WITH_TWO_FINGERS_TO_SEND_A_DECLINE_MESSAGE;
+
}
#endif // __CALLUI_RESOURCES_H__
void deactivateRotary();
void setAcceptBtnType(AcceptButtonType type);
+ // Screen Reader
+ ucl::ElmWidget *getAcceptAo();
+ ucl::ElmWidget *getRejectAo();
+
private:
friend class ucl::ReffedObj<AcceptRejectWidget>;
AcceptRejectWidget(ucl::IRefCountObj &rc,
void setAcceptUnpressedState();
void setRejectUnpressedState();
+ // Screen Reader
+ ucl::Result registerAccessObjects(
+ ucl::ElmWidget &widget);
+
private:
ucl::Layout *m_layout;
NotiHandler m_accHandler;
int m_rejBCAnimIndex;
AcceptButtonType m_acceptBtnType;
+
+ // Screen Reader
+ ucl::ElmWidgetSRef m_accAo;
+ ucl::ElmWidgetSRef m_rejAo;
};
}
virtual void setValue(int value) override final;
+ // Screen Reader
+ ucl::ElmWidget *getDecreaseBtn();
+ ucl::ElmWidget *getIncreaseBtn();
+ ucl::ElmWidget *getValueTxtAo();
+
private:
friend class ucl::ReffedObj<VolumeControl>;
VolumeControl(ucl::IRefCountObj &rc,
void onDecreaseBtnClickedCb(ucl::Widget &widget, void *eventInfo);
void onIncreaseBtnClickedCb(ucl::Widget &widget, void *eventInfo);
+ void onWidgetShowCb(Widget &widget, void *eventInfo);
+ void onWidgetHideCb(Widget &widget, void *eventInfo);
+
+ // Screen Reader
+ void registerAccessObjectInformation();
+
private:
ucl::StyledWidget m_decreaseBtn;
ucl::StyledWidget m_increaseBtn;
VolumeControlEventHandler m_handler;
+
+ // Screen Reader
+ ucl::ElmWidgetSRef m_valueTxtAo;
};
}
#include <efl_extension.h>
-#include "types.h"
-
-namespace ucl {
+#include "ucl/gui/ElmWidget.h"
+#include "ucl/gui/Naviframe.h"
+#include "ucl/gui/Layout.h"
- class ElmWidget;
- class Naviframe;
-}
+#include "types.h"
-namespace callui {
+namespace callui { namespace utils {
ucl::Result createCircleSurface(ucl::Naviframe &navi);
Eext_Circle_Surface *getCircleSurface(const ucl::ElmWidget &widget);
- void addRotaryEventHandler(Eext_Rotary_Handler_Cb func, void *data);
-
- void delRotaryEventHandler(Eext_Rotary_Handler_Cb func, void *data);
+ ucl::ElmWidgetSRef createFakeAccessObject(ucl::ElmWidget &parent);
Elm_Genlist_Item_Class createGenlistItemClass(const char *style,
Elm_Gen_Item_Text_Get_Cb txtCb = nullptr,
Elm_Gen_Item_State_Get_Cb stateCb = nullptr,
Elm_Gen_Item_Del_Cb delCb = nullptr);
+ ucl::ElmWidgetSRef createAccessObject(ucl::ElmWidget &parent,
+ ucl::Widget &ly);
+
+ ucl::ElmWidgetSRef createAccessObjectFromLyPart(ucl::ElmWidget &parent,
+ ucl::Widget &ly,
+ const ucl::EdjePart &lyPart);
+
+ void destroyAccessObject(ucl::ElmWidget &ao);
+
+}}
+
+namespace callui {
+
+ void addRotaryEventHandler(Eext_Rotary_Handler_Cb func, void *data);
+
+ void delRotaryEventHandler(Eext_Rotary_Handler_Cb func, void *data);
+
ucl::LayoutTheme getImageTheme(const char *fileName);
+
+ Elm_Atspi_Relation_Type getFlowRelation(Elm_Atspi_Gesture_Info gestureInfo);
+
}
#endif // __CALLUI_VIEW_HELPERS_H__
{
}
- AcceptDialog::Builder &AcceptDialog::Builder::setHandler(AcceptDialogHandler handler)
+ AcceptDialog::Builder &
+ AcceptDialog::Builder::setHandler(AcceptDialogHandler handler)
{
m_handler = handler;
return *this;
if (!popupEo) {
LOG_RETURN(RES_FAIL, "elm_popup_add() failed!");
}
- evas_object_size_hint_weight_set(popupEo, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
-
m_popup = makeShared<StyledWidget>(popupEo, true);
m_popup->setStyle(style);
-
+ m_popup->setWeight(EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
show(*m_popup);
m_popup->addEventHandler(impl::POPUP_DISMISSED, WEAK_DELEGATE(
if (!glEo) {
LOG_RETURN(RES_FAIL, "elm_genlist_add() failed!");
}
- evas_object_size_hint_weight_set(glEo, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
- evas_object_size_hint_align_set(glEo, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_genlist_mode_set(glEo, ELM_LIST_COMPRESS);
elm_genlist_homogeneous_set(glEo, EINA_TRUE);
m_genlist = makeShared<StyledWidget>(glEo);
+ m_genlist->setWeight(EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ m_genlist->setAlign(EVAS_HINT_FILL, EVAS_HINT_FILL);
- Evas_Object *circleGlEo = eext_circle_object_genlist_add(glEo, getCircleSurface(*m_genlist));
- eext_circle_object_genlist_scroller_policy_set(circleGlEo, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_AUTO);
+ Evas_Object *circleGlEo = eext_circle_object_genlist_add(glEo,
+ utils::getCircleSurface(*m_genlist));
+ eext_circle_object_genlist_scroller_policy_set(circleGlEo,
+ ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_AUTO);
eext_rotary_object_event_activated_set(circleGlEo, EINA_TRUE);
FAIL_RETURN(fillGenlist(), "fillGenlist() failed!");
Result AcceptDialog::addGenlistTitleItem()
{
- static Elm_Genlist_Item_Class titleItc = createGenlistItemClass("title",
+ static Elm_Genlist_Item_Class titleItc =
+ utils::createGenlistItemClass("title",
[](void *data, Evas_Object *obj, const char *part) -> char * {
return strdup(STR_ANSWER_CALL.translate());
});
Result AcceptDialog::addGenlistTextItem(AcceptDialogEvent event)
{
- static Elm_Genlist_Item_Class textItc = createGenlistItemClass("1text.1icon",
+ static Elm_Genlist_Item_Class textItc =
+ utils::createGenlistItemClass("1text.1icon",
[](void *data, Evas_Object *obj, const char *part) -> char * {
switch (impl::asEvent(data)) {
case AcceptDialogEvent::HOLD_AND_ACCEPT:
Result AcceptDialog::addGenlistBottomItem()
{
- static Elm_Genlist_Item_Class paddingItc = createGenlistItemClass("1text.1icon");
-
+ static Elm_Genlist_Item_Class paddingItc =
+ utils::createGenlistItemClass("1text.1icon");
Elm_Object_Item *item = elm_genlist_item_append(*m_genlist, &paddingItc,
nullptr,
nullptr,
AcceptButtonType::SIMPLE);
}
+ // Screen Reader
+ ElmWidget *AcceptRejectPresenter::getAcceptAo()
+ {
+ return m_widget->getAcceptAo();
+ }
+ ElmWidget *AcceptRejectPresenter::getRejectAo()
+ {
+ return m_widget->getRejectAo();
+ }
}
constexpr EdjeSignal SIGNAL_TURN_ON {"turn.on"};
constexpr EdjeSignal SIGNAL_TURN_OFF {"turn.off"};
+
+ constexpr SmartEvent EVENT_ACCESS_READ_START {"access,read,start"};
}}}
namespace callui {
m_vcTimer(nullptr),
m_audioState(m_sm->getAudioState()),
m_mode(ComponentsMode::UNDEFINED),
- m_exitHandler(handler)
+ m_exitHandler(handler),
+ m_isVcShowOnRotaryEvent(false)
{
}
Result AccessoryPresenter::prepare(GuiPresenter &parent,
ElmWidget &parentWidget, const ICallManagerSRef &cm)
{
- FAIL_RETURN(GuiPresenter::prepare(parent), "Presenter::prepare() failed");
+ FAIL_RETURN(GuiPresenter::prepare(parent),
+ "Presenter::prepare() failed");
- FAIL_RETURN(createWidget(parentWidget), "createWidget() failed");
+ FAIL_RETURN(createWidget(parentWidget),
+ "createWidget() failed");
- FAIL_RETURN(createSlider(), "createSlider() failed");
+ FAIL_RETURN(createSlider(),
+ "createSlider() failed");
- FAIL_RETURN(createVolumeControl(), "createVolumeControl() failed");
+ FAIL_RETURN(createVolumeControl(),
+ "createVolumeControl() failed");
updateVolume(m_sm->getVolume());
updateMode(cm);
- FAIL_RETURN(updateModeRelativeComponents(cm), "updateComponents() failed");
+ FAIL_RETURN(updateModeRelativeComponents(cm),
+ "updateComponents() failed");
return RES_OK;
}
Result AccessoryPresenter::update(const ICallManagerSRef &cm)
{
- auto curMode = getCurrentMode(cm);
- if (m_mode == curMode) {
- LOG_RETURN(RES_OK, "Mode is the same. No need to update");
- }
- m_mode = curMode;
+ updateMode(cm);
- FAIL_RETURN(updateModeRelativeComponents(cm), "updateComponents() failed");
+ FAIL_RETURN(updateModeRelativeComponents(cm),
+ "updateModeRelativeComponents() failed");
return RES_OK;
}
m_vc->resize(w, h);
hide(*m_vc);
+ registerVolumeControlAo();
+
return RES_OK;
}
asWeak(*this)));
show(*m_volumeBtn);
+ // Screen Reader
+ elm_atspi_accessible_translation_domain_set(*m_volumeBtn, PACKAGE);
+ elm_atspi_accessible_name_set(*m_volumeBtn, AO_STR_VOLUME);
+
return RES_OK;
}
show(*m_muteBtn);
+ // Screen Reader
+ elm_atspi_accessible_translation_domain_set(*m_muteBtn, PACKAGE);
+ elm_atspi_accessible_name_set(*m_muteBtn, AO_STR_MUTE);
+
return RES_OK;
}
show(*m_bluetoothBtn);
- (m_audioState == AudioStateType::BT) ?
- m_bluetoothBtn->emit(impl::SIGNAL_TURN_ON) :
- m_bluetoothBtn->emit(impl::SIGNAL_TURN_OFF);
+ // Screen Reader
+ elm_atspi_accessible_translation_domain_set(*m_bluetoothBtn, PACKAGE);
+ if (m_audioState == AudioStateType::BT) {
+ m_bluetoothBtn->emit(impl::SIGNAL_TURN_ON);
+ // Screen Reader
+ elm_atspi_accessible_name_set(*m_bluetoothBtn,
+ AO_STR_GEAR_SPK);
+ } else {
+ m_bluetoothBtn->emit(impl::SIGNAL_TURN_OFF);
+ // Screen Reader
+ elm_atspi_accessible_name_set(*m_bluetoothBtn,
+ AO_STR_HEADSET);
+ }
+
if (!m_sm->isBTSupported()) {
disable(*m_bluetoothBtn);
}
asWeak(*this)));
show(*m_addContactBtn);
+ // Screen Reader
+ elm_atspi_accessible_translation_domain_set(*m_addContactBtn, PACKAGE);
+ elm_atspi_accessible_name_set(*m_addContactBtn,
+ AO_STR_ADD_TO_CONTACTS);
+
return RES_OK;
}
show(*m_vc);
startVCTimer();
+
+ elm_atspi_component_highlight_grab(*m_vc);
}
void AccessoryPresenter::onMuteBtnClicked(Widget &widget, void *eventInfo)
{
stopVCTimer();
- m_vcTimer = ecore_timer_add(CALL_VC_TIMER_INTERVAL,
+ auto timerInterval = CALL_VC_TIMER_INTERVAL;
+ if (elm_atspi_bridge_utils_is_screen_reader_enabled()) {
+ timerInterval = CALL_VC_SCREEN_READER_TIMER_INTERVAL;
+ }
+
+ m_vcTimer = ecore_timer_add(timerInterval,
CALLBACK_B(AccessoryPresenter::onVCTimerCb),
this);
}
Eina_Bool AccessoryPresenter::onRotaryEvent(Eext_Rotary_Event_Info *info)
{
if (!isActive()) {
- LOG_RETURN_VALUE(RES_OK, EINA_TRUE, "Presenter is not active. Ignore");
+ LOG_RETURN_VALUE(RES_OK, EINA_TRUE,
+ "Presenter is not active. Ignore");
}
if (m_vcTimer) {
} else {
show(*m_vc);
startVCTimer();
+ m_isVcShowOnRotaryEvent = true;
+ elm_atspi_component_highlight_grab(*m_vc);
+ }
+
+ if (m_isVcShowOnRotaryEvent) {
+ m_isVcShowOnRotaryEvent = checkPossibilityToModifyVolume(
+ m_sm->getVolume(),
+ info->direction ==
+ EEXT_ROTARY_DIRECTION_CLOCKWISE);
}
if (info->direction == EEXT_ROTARY_DIRECTION_CLOCKWISE) {
}
}
+ bool AccessoryPresenter::checkPossibilityToModifyVolume(int volume, bool needIncrease)
+ {
+ if (needIncrease) {
+ auto max = m_sm->getMaxVolume();
+ return (max >= volume);
+ } else {
+ return (volume - 1 >= VOLUME_LEVEL_MIN);
+ }
+ return false;
+ }
+
void AccessoryPresenter::tryIncreaseVolume()
{
- auto max = m_sm->getMaxVolume();
auto cur = m_sm->getVolume();
-
- if (max != cur) {
- m_sm->setVolume(cur + 1);
+ if (checkPossibilityToModifyVolume(cur, true)) {
+ FAIL_RETURN_VOID(m_sm->setVolume(cur + 1),
+ "setVolume() failed");
}
}
void AccessoryPresenter::tryDecreaseVolume()
{
auto cur = m_sm->getVolume();
-
- if (cur - 1 >= VOLUME_LEVEL_MIN) {
- m_sm->setVolume(cur - 1);
+ if (checkPossibilityToModifyVolume(cur, false)) {
+ FAIL_RETURN_VOID(m_sm->setVolume(cur - 1),
+ "setVolume() failed");
}
}
updateVolume(m_sm->getVolume());
if (m_bluetoothBtn) {
- (m_audioState == AudioStateType::BT) ?
- m_bluetoothBtn->emit(impl::SIGNAL_TURN_ON) :
- m_bluetoothBtn->emit(impl::SIGNAL_TURN_OFF);
+
+ if (m_audioState == AudioStateType::BT) {
+ m_bluetoothBtn->emit(impl::SIGNAL_TURN_ON);
+ // Screen Reader
+ elm_atspi_accessible_name_set(*m_bluetoothBtn,
+ AO_STR_GEAR_SPK);
+ } else {
+ m_bluetoothBtn->emit(impl::SIGNAL_TURN_OFF);
+ // Screen Reader
+ elm_atspi_accessible_name_set(*m_bluetoothBtn,
+ AO_STR_HEADSET);
+ }
}
}
}
m_vc->setIncreaseBtnEnable(true);
m_vc->setDecreaseBtnEnable(true);
}
+
+ // Screen Reader
+ if (m_vc->isVisible()) {
+ if (!m_isVcShowOnRotaryEvent) {
+ elm_atspi_bridge_utils_say(std::to_string(cur).c_str(),
+ EINA_FALSE, nullptr, nullptr);
+ }
+ m_isVcShowOnRotaryEvent = false;
+ }
}
void AccessoryPresenter::onVolumeLevelChanged(int value)
isMuted ? m_muteBtn->emit(impl::SIGNAL_TURN_ON) :
m_muteBtn->emit(impl::SIGNAL_TURN_OFF);
}
+
+ // Screen Reader
+ ElmWidget *AccessoryPresenter::getVolumBtn()
+ {
+ return m_volumeBtn.get();
+ }
+
+ ElmWidget *AccessoryPresenter::getBluetoothBtn()
+ {
+ return m_bluetoothBtn.get();
+ }
+
+ ElmWidget *AccessoryPresenter::getMuteBtn()
+ {
+ return m_muteBtn.get();
+ }
+
+ ElmWidget *AccessoryPresenter::getAddContactBtn()
+ {
+ return m_addContactBtn.get();
+ }
+
+ ElmWidget *AccessoryPresenter::getVolumeControlLy()
+ {
+ return m_vc.get();
+ }
+
+ ElmWidget *AccessoryPresenter::getVolumeControlDecreaseBtn()
+ {
+ return m_vc->getDecreaseBtn();
+ }
+
+ ElmWidget *AccessoryPresenter::getVolumeControlIncreaseBtn()
+ {
+ return m_vc->getIncreaseBtn();
+ }
+
+ ElmWidget *AccessoryPresenter::getVolumeControlValueTxtAo()
+ {
+ return m_vc->getValueTxtAo();
+ }
+
+ void AccessoryPresenter::registerVolumeControlAo()
+ {
+ auto decrBtn = m_vc->getDecreaseBtn();
+ if (decrBtn) {
+ decrBtn->addEventHandler(impl::EVENT_ACCESS_READ_START,
+ WEAK_DELEGATE(AccessoryPresenter::
+ onVolumeControlScreenReaderReadStart,
+ asWeak(*this)));
+ }
+
+ auto incrBtn = m_vc->getIncreaseBtn();
+ if (incrBtn) {
+ incrBtn->addEventHandler(impl::EVENT_ACCESS_READ_START,
+ WEAK_DELEGATE(AccessoryPresenter::
+ onVolumeControlScreenReaderReadStart,
+ asWeak(*this)));
+ }
+ }
+
+ void AccessoryPresenter::onVolumeControlScreenReaderReadStart(
+ Widget &widget,
+ void *eventInfo)
+ {
+ restartVCTimer();
+ }
+
}
--- /dev/null
+/*
+ * Copyright 2017 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * 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.
+ */
+
+#include "presenters/AtspiHighlightHelper.h"
+
+#include "common.h"
+
+namespace callui { namespace { namespace impl {
+
+ constexpr EoDataKey ATSPI_HELPER_DATA {"callui,atspi,highlight,helper"};
+}}}
+
+namespace callui {
+
+ using ucl::AtspiGestureEventInfo;
+
+ using ucl::ATSPI_ON_GESTURE;
+
+ AtspiHighlightHelperSRef AtspiHighlightHelper::newInstance(
+ GuiPresenter &parent, ElmWidget &rootWidget)
+ {
+ auto result = makeShared<AtspiHighlightHelper>();
+
+ FAIL_RETURN_VALUE(result->prepare(parent, rootWidget), {},
+ "result->prepare() failed!");
+
+ return result;
+ }
+
+ AtspiHighlightHelper::AtspiHighlightHelper(IRefCountObj &rc) :
+ GuiPresenter(rc)
+ {
+ }
+
+ AtspiHighlightHelper::~AtspiHighlightHelper()
+ {
+ }
+
+ Result AtspiHighlightHelper::prepare(GuiPresenter &parent,
+ ElmWidget &rootWidget)
+ {
+ FAIL_RETURN(GuiPresenter::prepare(parent),
+ "GuiPresenter::prepare() failed!");
+
+ registerWidget(rootWidget);
+
+ return RES_OK;
+ }
+
+ void AtspiHighlightHelper::setRelationEventHandler(RelationEventHandler handler)
+ {
+ m_relationEventHandler = handler;
+ }
+
+ void AtspiHighlightHelper::setGestureEventHandler(GestureEventHandler handler)
+ {
+ m_gestureEventHandler = handler;
+ }
+
+ void AtspiHighlightHelper::registerWidget(ElmWidget &widget)
+ {
+ DLOG("this [%p] widget [%p]", this, widget.getEo());
+
+ widget.addEventHandler(ATSPI_ON_GESTURE, WEAK_DELEGATE(
+ AtspiHighlightHelper::onAtspiGesture, asWeak(*this)));
+ }
+
+ void AtspiHighlightHelper::handleAtspiGesture(
+ Elm_Interface_Atspi_Accessible *ao,
+ AtspiGestureEventInfo &e)
+ {
+ DLOG("this [%p] ao [%p]", this, ao);
+
+ if (e.stopPropagation) {
+ DLOG("e.stopPropagation");
+ return;
+ }
+
+ if (!isActive()) {
+ DLOG("!isActive()");
+ if (e.gestureInfo.type != ELM_ATSPI_GESTURE_ONE_FINGER_SINGLE_TAP) {
+ e.preventDefault = true;
+ }
+ return;
+ }
+
+ e.stopPropagation = true;
+
+ if (m_gestureEventHandler) {
+ DLOG("m_gestureEventHandler");
+ if (m_gestureEventHandler(ao, e.gestureInfo.type)) {
+ e.preventDefault = true;
+ return;
+ }
+ }
+
+ e.preventDefault = false;
+
+ if (!m_relationEventHandler) {
+ DLOG("!m_relationEventHandler");
+ return;
+ }
+
+ const Elm_Atspi_Relation_Type relation = getFlowRelation(e.gestureInfo);
+ if (relation == ELM_ATSPI_RELATION_NULL) {
+ return;
+ }
+
+ const auto relationObj = m_relationEventHandler(ao, relation);
+ if (!relationObj) {
+ return;
+ }
+
+ auto &win = getWindow();
+ auto atspiHelper = static_cast<Elm_Interface_Atspi_Accessible *>
+ (win.getData(impl::ATSPI_HELPER_DATA));
+
+ if (!atspiHelper) {
+ const auto obj = utils::createFakeAccessObject(win);
+ if (!obj) {
+ LOG_RETURN_VOID(RES_FAIL, "createFakeAccessObject() failed!");
+ }
+ obj->setIsOwner(false);
+ atspiHelper = obj->getEo();
+ win.setData(impl::ATSPI_HELPER_DATA, atspiHelper);
+ }
+
+ if (ao == win) {
+ ao = atspiHelper;
+ elm_atspi_component_highlight_grab(ao);
+ }
+
+ elm_atspi_accessible_relationships_clear(ao);
+ elm_atspi_accessible_relationship_append(ao, relation, relationObj);
+ }
+
+ void AtspiHighlightHelper::onAtspiGesture(
+ Widget &widget, void *eventInfo)
+ {
+ handleAtspiGesture(widget,
+ *static_cast<AtspiGestureEventInfo *>(eventInfo));
+ }
+
+ bool AtspiHighlightHelper::handleGesture(Elm_Interface_Atspi_Accessible *ao,
+ const Elm_Atspi_Gesture_Info &info)
+ {
+ AtspiGestureEventInfo eventInfo {};
+ eventInfo.gestureInfo = info;
+
+ handleAtspiGesture(ao, eventInfo);
+
+ return eventInfo.preventDefault;
+ }
+}
"<align=center><color=#4dcfffff><font_size=24>%s"
"</color></font_size></align>"};
+ constexpr EdjePart PART_AO_MAIN_TXT {"ao_text_1line"};
+ constexpr EdjePart PART_AO_SUB_TXT {"ao_text_2line"};
+
int getTextWidth(ElmWidget &parent, const char *fontStyle,
int fontSize, const std::string &text)
{
m_widget->setContent(*m_label, impl::PART_SWL_2LINE);
+ elm_atspi_accessible_can_highlight_set(*m_label, EINA_FALSE);
+
return RES_OK;
}
m_widget->emit(impl::SIGN_DEFAULT, impl::SRC_TXT_2LINE);
}
+ FAIL_RETURN(setSubTxtAccessObject(subTxt),
+ "setSubTxtAccessObject() failed!");
+
return RES_OK;
}
}
void CallInfoPresenter::displayMainTxt(const ICallInfoSCRef &info,
- const std::string &text) const
+ const std::string &text)
{
m_widget->setText(text.c_str(), impl::PART_TXT_MAIN);
+ FAIL_RETURN_VOID(setMainTxtAccessObject(text),
+ "setMainTxtAccessObject() failed!");
+
if (m_mode == CallMode::INCOMING) {
// Font size and color
if (m_callerId) {
return RES_OK;
}
+ // Screen Reader
+ ElmWidget *CallInfoPresenter::getMainTxtAo()
+ {
+ return m_mainTxtAO.get();
+ }
+
+ ElmWidget *CallInfoPresenter::getSubTxtAo()
+ {
+ return m_subTxtAO.get();
+ }
+
+ ElmWidget *CallInfoPresenter::getStatusTxtAo()
+ {
+ return m_callStatus->getStatusTextAo();
+ }
+
+ Result CallInfoPresenter::setMainTxtAccessObject(const std::string &text)
+ {
+ if (!m_mainTxtAO) {
+ m_mainTxtAO = utils::createAccessObjectFromLyPart(*m_widget,
+ *m_widget,
+ impl::PART_AO_MAIN_TXT);
+ if (!m_mainTxtAO) {
+ LOG_RETURN(RES_FAIL, "createAccessObjectFromLyPart() failed!");
+ }
+
+ }
+ elm_atspi_accessible_reading_info_type_set(*m_mainTxtAO,
+ ELM_ACCESSIBLE_READING_INFO_TYPE_NAME);
+ elm_atspi_accessible_name_set(*m_mainTxtAO, text.c_str());
+
+ return RES_OK;
+ }
+
+ Result CallInfoPresenter::setSubTxtAccessObject(const std::string &text)
+ {
+ if (!text.empty()) {
+ if (!m_subTxtAO) {
+ m_subTxtAO = utils::createAccessObjectFromLyPart(*m_widget,
+ *m_widget,
+ impl::PART_AO_SUB_TXT);
+ if (!m_subTxtAO) {
+ LOG_RETURN(RES_FAIL, "createAccessObjectFromLyPart() failed!");
+ }
+ }
+
+ elm_atspi_accessible_reading_info_type_set(*m_subTxtAO,
+ ELM_ACCESSIBLE_READING_INFO_TYPE_NAME);
+ elm_atspi_accessible_name_set(*m_subTxtAO, text.c_str());
+
+ } else if (m_subTxtAO) {
+ utils::destroyAccessObject(*m_subTxtAO);
+ m_subTxtAO.reset();
+ }
+
+ return RES_OK;
+ }
}
constexpr EdjeSignal SIGN_DOT_LTR {"default:LTR"};
constexpr EdjeSignal SIGN_RESET {"reset"};
+ constexpr EdjePart PART_AO_STATUS {"ao_text_info"};
+
constexpr EdjeSignalSrc SIGN_SRC_DOT {"dot"};
}}}
m_ly->emit(impl::SIGN_RESET, impl::SIGN_SRC_DOT);
m_ly->setText("", impl::PART_TXT_TEXT_INFO);
+ createStatusTxtAo();
switch (m_mode) {
case CallMode::INCOMING: return processIncomingMode();
if (const auto info = m_info.lock()) {
m_duration = info->getDuration();
}
- setCallDuration(m_duration, *m_ly, impl::PART_TXT_TEXT_INFO);
+ m_ly->setText(getCallDuration(m_duration),
+ impl::PART_TXT_TEXT_INFO);
if (m_timer) {
ecore_timer_del(m_timer);
Eina_Bool CallStatusPresenter::onBlinkingTimerCb()
{
if ((m_blinkCount % 2) == 0) {
- setCallDuration(m_duration, *m_ly, impl::PART_TXT_TEXT_INFO);
+ m_ly->setText(getCallDuration(m_duration),
+ impl::PART_TXT_TEXT_INFO);
} else if ((m_blinkCount % 2) == 1) {
m_ly->setText("", impl::PART_TXT_TEXT_INFO);
}
return RES_OK;
}
+ // Screen Reader
+ Result CallStatusPresenter::createStatusTxtAo()
+ {
+ if (!m_statusTxtAo) {
+ m_statusTxtAo = utils::createAccessObjectFromLyPart(*m_ly,
+ *m_ly,
+ impl::PART_AO_STATUS);
+ if (!m_statusTxtAo) {
+ LOG_RETURN(RES_FAIL, "createAccessObjectFromLyPart() failed!");
+ }
+
+ elm_atspi_accessible_reading_info_type_set(*m_statusTxtAo,
+ ELM_ACCESSIBLE_READING_INFO_TYPE_NAME);
+ elm_atspi_accessible_name_cb_set(*m_statusTxtAo,
+ [](void *data, Evas_Object *obj) -> char *
+ {
+ auto self = static_cast<CallStatusPresenter *>(data);
+ if (!self) {
+ return nullptr;
+ }
+ auto txt = self->m_ly->
+ getText(impl::PART_TXT_TEXT_INFO).getCStr();
+ return (txt) ? strdup(txt) : nullptr;
+ },
+ this);
+ }
+ return RES_OK;
+ }
+
+ ElmWidget *CallStatusPresenter::getStatusTextAo()
+ {
+ return m_statusTxtAo.get();
+ }
+
}
}
m_win->getConformant().setContent(*m_navi);
+ elm_atspi_accessible_translation_domain_set(*m_win, PACKAGE);
+ elm_atspi_accessible_name_set(*m_win, AO_STR_CALL);
- FAIL_RETURN(createCircleSurface(*m_navi),
+ FAIL_RETURN(utils::createCircleSurface(*m_navi),
"createCircleSurface() failed!");
m_sysEventProvider.addEventHandler(
#include "presenters/MoreOptionsPresenter.h"
#include "presenters/DeviceStatePresenter.h"
+#include "presenters/AtspiHighlightHelper.h"
+
#include "resources.h"
#include "common.h"
constexpr EdjePart PART_SWL_OVERLAY {"swl.overlay"};
constexpr EdjePart PART_SWL_MORE_OPTION {"swl.more_option"};
- constexpr EdjePart PART_TXT_REJECT_MSG {"reject_msg_text"};
+ constexpr EdjePart PART_TXT_REJECT_MSG_CUE_AO {"ao_cue"};
+ constexpr EdjePart PART_TXT_REJECT_MSG {"reject_msg_text"};
constexpr ElmStyle STYLE_BB_END_CALL {"callui/end_call"};
constexpr ElmStyle STYLE_BB_RECALL {"callui/call_back"};
}}}
Result MainPage::processIncomingCallMode()
{
- m_bottomBtn.reset();
- m_moreOptionsPrs.reset();
m_accessoryPrs.reset();
auto call = m_cm->getIncomingCall();
if (!isUnknownCaller(*call->getInfo())
&& (provider && provider->getMsgCount() > 0)) {
- m_rmLy = Layout::Builder().
- setTheme(impl::LAYOUT_REJECT_MSG_WIDGET).
- setIsOwner(true).
- build(*m_widget);
- if (!m_rmLy) {
- LOG_RETURN(RES_FAIL, "Layout::build() failed!");
- }
- m_rmLy->setText(STR_DECLINE_MESSAGES, impl::PART_TXT_REJECT_MSG);
-
- m_widget->setContent(*m_rmLy, impl::PART_SWL_REJECT_MSG);
FAIL_RETURN(createRejectMsgPresenter(provider),
"createRejectMsgPresenter() failed!");
+
+ FAIL_RETURN(createRejectMsgCue(),
+ "craeteRejectMsgCue() failed!");
+
+ if (createRejectMsgCueAo() != RES_OK) {
+ ELOG("createRejectMsgCueAo() failed!");
+ }
}
if (m_indicator) {
return RES_OK;
}
- Result MainPage::processEndCallMode()
+ Result MainPage::createRejectMsgCue()
{
- m_bottomBtn.reset();
- m_moreOptionsPrs.reset();
+ m_rmLy = Layout::Builder().
+ setTheme(impl::LAYOUT_REJECT_MSG_WIDGET).
+ setIsOwner(true).
+ build(*m_widget);
+ if (!m_rmLy) {
+ LOG_RETURN(RES_FAIL, "Layout::build() failed!");
+ }
- m_rmPrs.reset();
- m_acceptRejectPrs.reset();
- m_rmLy.reset();
+ m_rmLy->setText(STR_DECLINE_MESSAGES, impl::PART_TXT_REJECT_MSG);
+ m_widget->setContent(*m_rmLy, impl::PART_SWL_REJECT_MSG);
+ return RES_OK;
+ }
+
+ Result MainPage::processEndCallMode()
+ {
if (m_indicator) {
m_indicator->udapteIncomingCallMode(false);
}
FAIL_RETURN(createAccessoryPresenter(),
"createAccessoryPresenter() failed");
+
+ auto end = m_cm->getEndCall();
+ if (end) {
+ auto info = end->getInfo();
+ if (info && info->getConferenceMemberCount() == 1) {
+ FAIL_RETURN(createBottomBtn(impl::STYLE_BB_RECALL, false),
+ "createBottomBtn() failed");
+ hide(*m_bottomBtn);
+ }
+ } else {
+ ELOG("End call is NULL!");
+ }
+
startEndCallTimer();
return RES_OK;
m_rmPrs.reset();
m_acceptRejectPrs.reset();
m_rmLy.reset();
+ m_rmCueAo.reset();
if (m_indicator) {
m_indicator->udapteIncomingCallMode(false);
}
}
- Result MainPage::createBottomBtn(const ElmStyle &style)
+ Result MainPage::createBottomBtn(const ElmStyle &style, bool setVisible)
{
m_bottomBtn = makeShared<StyledWidget>(
elm_button_add(*m_widget), true);
WEAK_DELEGATE(MainPage::onBottomBtnClicked,
asWeak(*this)));
- m_widget->setContent(*m_bottomBtn, impl::PART_SWL_BOTTOM_BTN);
- show(*m_bottomBtn);
+ elm_atspi_accessible_translation_domain_set(*m_bottomBtn, PACKAGE);
+ if (style == impl::STYLE_BB_RECALL) {
+ elm_atspi_accessible_name_set(*m_bottomBtn, AO_STR_CALLBACK);
+ } else {
+ elm_atspi_accessible_name_set(*m_bottomBtn, AO_STR_END_CALL);
+ }
+
+ if (setVisible) {
+ m_widget->setContent(*m_bottomBtn, impl::PART_SWL_BOTTOM_BTN);
+ show(*m_bottomBtn);
+ } else {
+ hide(*m_bottomBtn);
+ }
return RES_OK;
}
Eina_Bool MainPage::onEndCallTimerCb()
{
- auto end = m_cm->getEndCall();
- if (!end) {
- m_ecTimer = nullptr;
- requestExit();
- LOG_RETURN_VALUE(RES_FAIL, ECORE_CALLBACK_CANCEL, "end is NULL");
- }
-
- auto info = end->getInfo();
- if (!m_bottomBtn && !m_ecTimerBtnReq) {
- if (info && info->getConferenceMemberCount() == 1) {
- if (createBottomBtn(impl::STYLE_BB_RECALL) != RES_OK) {
- m_ecTimer = nullptr;
- requestExit();
- LOG_RETURN_VALUE(RES_FAIL, ECORE_CALLBACK_CANCEL,
- "createBottomBtn() failed!");
- }
+ if (!m_ecTimerBtnReq) {
+ if (!m_bottomBtn) {
+ m_ecTimer = nullptr;
+ requestExit();
+ LOG_RETURN_VALUE(RES_FAIL, ECORE_CALLBACK_CANCEL, "bottom button is NULL!");
}
+ m_widget->setContent(*m_bottomBtn, impl::PART_SWL_BOTTOM_BTN);
+ show(*m_bottomBtn);
+
ecore_timer_interval_set(m_ecTimer, impl::CU_EXIT_APP_TIMEOUT);
m_ecTimerBtnReq = true;
+
return ECORE_CALLBACK_RENEW;
} else {
m_ecTimer = nullptr;
requestExit();
+
return ECORE_CALLBACK_CANCEL;
}
}
FAIL_RETURN_VOID(showWindow(), "showWindow failed!");
+ m_acceptRejectPrs.reset();
+ m_rmPrs.reset();
+ m_moreOptionsPrs.reset();
+ m_callInfoPrs.reset();
+
+ m_rmLy.reset();
+ m_rmCueAo.reset();
+ m_bottomBtn.reset();
+
switch (m_mode) {
case CallMode::INCOMING:
FAIL_RETURN_VOID(processIncomingCallMode(),
"createCallInfoPresenter() failed!");
FAIL_RETURN_VOID(updateDeviceState(prevMode, m_mode),
- "createCallInfoPresenter() failed!");
+ "updateDeviceState() failed!");
+
+ createAtspiHighlightHelper();
}
Result MainPage::updateDeviceState(CallMode prevMode, CallMode curMode)
return RES_OK;
}
- bool MainPage::detectMuteControlDisableState()
- {
- return (m_mode == CallMode::OUTGOING ||
- (m_mode == CallMode::DURING &&
- (m_cm->getAvailableCalls() == CALL_FLAG_HELD)));
- }
-
Result MainPage::createWidget()
{
m_widget = Layout::Builder().
LOG_RETURN(RES_FAIL, "Indicator::build() failed!");
}
- m_widget->setContent(m_indicator->getWidget(), impl::PART_SWL_INDICATOR);
+ m_widget->setContent(m_indicator->getWidget(),
+ impl::PART_SWL_INDICATOR);
return RES_OK;
}
void MainPage::RejectMsgStateCb(RejectMsgState state)
{
- (state == RejectMsgState::HIDDEN) ?
- show(*m_rmLy) : hide(*m_rmLy);
+ if (state == RejectMsgState::HIDDEN) {
+ show(*m_rmLy);
+ show(*m_rmCueAo);
+ } else {
+ hide(*m_rmLy);
+ hide(*m_rmCueAo);
+ }
}
void MainPage::RejectMsgSelectCb(const IRejectMsgSRef &rm)
"RejectMessagePresenter::build() failed!");
}
- m_widget->setContent(m_rmPrs->getWidget(), impl::PART_SWL_OVERLAY);
+ m_widget->setContent(m_rmPrs->getWidget(),
+ impl::PART_SWL_OVERLAY);
return RES_OK;
}
}
}
+ // Screen Reader
+ Result MainPage::createRejectMsgCueAo()
+ {
+ m_rmCueAo = utils::createAccessObjectFromLyPart(*m_widget,
+ *m_rmLy,
+ impl::PART_TXT_REJECT_MSG_CUE_AO);
+ if (!m_rmCueAo) {
+ LOG_RETURN(RES_FAIL, "createAccessObjectFromLyPart() failed!");
+ }
+ elm_atspi_accessible_translation_domain_set(*m_rmCueAo, PACKAGE);
+ elm_atspi_accessible_reading_info_type_set(*m_rmCueAo,
+ ELM_ACCESSIBLE_READING_INFO_TYPE_NAME |
+ ELM_ACCESSIBLE_READING_INFO_TYPE_DESCRIPTION);
+ elm_atspi_accessible_name_set(*m_rmCueAo, AO_STR_DECLINE_MESSAGES);
+ elm_atspi_accessible_description_set(*m_rmCueAo,
+ AO_STR_SWIPE_UP_WITH_TWO_FINGERS_TO_SEND_A_DECLINE_MESSAGE);
+
+ elm_atspi_accessible_gesture_cb_set(*m_rmCueAo,
+ [](void *data, Elm_Atspi_Gesture_Info gesture, Evas_Object *obj) {
+ // TODO: ELM_ATSPI_GESTURE_TWO_FINGERS_HOVER must be replaced
+ if (gesture.type == ELM_ATSPI_GESTURE_TWO_FINGERS_HOVER) {
+ auto page = (MainPage *)data;
+ page->m_rmPrs->showPanel();
+ return EINA_TRUE;
+ }
+
+ return EINA_FALSE;
+ }, this);
+
+ return RES_OK;
+ }
+
+ Result MainPage::createAtspiHighlightHelper()
+ {
+ m_atspiHelper = AtspiHighlightHelper::newInstance(*this, getWindow());
+ if (!m_atspiHelper) {
+ LOG_RETURN(RES_FAIL,
+ "AtspiHighlightHelper::newInstance() failed!");
+ }
+
+ switch (m_mode) {
+ case CallMode::INCOMING:
+ registerIncomingCallModeAo();
+ break;
+ case CallMode::OUTGOING:
+ case CallMode::DURING:
+ registerActiveCallModeAo();
+ break;
+ case CallMode::END:
+ registerEndCallModeAo();
+ default:
+ break;
+ }
+ return RES_OK;
+ }
+
+ void MainPage::registerIncomingCallModeAo()
+ {
+ DLOG("ENTER");
+ m_atspiHelper->setRelationEventHandler(WEAK_DELEGATE(
+ MainPage::onIncomingCallModeAtspiHighlight, asWeak(*this)));
+
+ m_atspiHelper->setGestureEventHandler(WEAK_DELEGATE(
+ MainPage::onIncomingModeAtspiGesture, asWeak(*this)));
+
+ auto acceptAO = m_acceptRejectPrs->getAcceptAo();
+ if (!acceptAO) {
+ DLOG("acceptAO is NULL");
+ } else {
+ m_atspiHelper->registerWidget(*acceptAO);
+ }
+
+ auto rejectAo = m_acceptRejectPrs->getRejectAo();
+ if (!rejectAo) {
+ DLOG("rejectAo is NULL");
+ } else {
+ m_atspiHelper->registerWidget(*rejectAo);
+ }
+
+ auto statusTxtAo = m_callInfoPrs->getStatusTxtAo();
+ if (!statusTxtAo) {
+ DLOG("statusTxtAo is NULL");
+ } else {
+ m_atspiHelper->registerWidget(*statusTxtAo);
+ }
+
+ auto mainTxtAo = m_callInfoPrs->getMainTxtAo();
+ if (!mainTxtAo) {
+ DLOG("mainTxtAo is NULL");
+ } else {
+ m_atspiHelper->registerWidget(*mainTxtAo);
+ }
+
+ auto subTxtAo = m_callInfoPrs->getSubTxtAo();
+ if (!subTxtAo) {
+ DLOG("subTxtAo is NULL");
+ } else {
+ m_atspiHelper->registerWidget(*subTxtAo);
+ }
+
+ if (!m_rmCueAo) {
+ DLOG("m_rmCueAo is NULL");
+ } else {
+ m_atspiHelper->registerWidget(*m_rmCueAo);
+ }
+
+ DLOG("EXIT");
+ }
+
+ bool MainPage::onIncomingModeAtspiGesture(Elm_Interface_Atspi_Accessible *widget,
+ Elm_Atspi_Gesture_Type gestureType)
+ {
+ DLOG(" GESTURE TYPE [%d]", gestureType);
+
+ if (m_rmCueAo && widget == *m_rmCueAo) {
+ if (gestureType == ELM_ATSPI_GESTURE_TWO_FINGERS_HOVER) {
+ m_rmPrs->showPanel();
+ return true;
+ }
+ }
+ return false;
+ }
+
+ Elm_Interface_Atspi_Accessible *MainPage::onIncomingCallModeAtspiHighlight(
+ Elm_Interface_Atspi_Accessible *ao,
+ Elm_Atspi_Relation_Type flowRelation)
+ {
+ DLOG("FlowRelation [%s]",
+ flowRelation == ELM_ATSPI_RELATION_FLOWS_FROM ?
+ "FROM" : "TO");
+
+ auto acceptAo = m_acceptRejectPrs->getAcceptAo();
+ auto rejectAo = m_acceptRejectPrs->getRejectAo();
+ auto statusTxtAo = m_callInfoPrs->getStatusTxtAo();
+ auto mainTxtAo = m_callInfoPrs->getMainTxtAo();
+ auto subTxtAo = m_callInfoPrs->getSubTxtAo();
+
+ if (ao == *acceptAo) {
+ if (flowRelation == ELM_ATSPI_RELATION_FLOWS_TO) {
+ return *statusTxtAo;
+ }
+ } else if (ao == *statusTxtAo) {
+ if (flowRelation == ELM_ATSPI_RELATION_FLOWS_TO) {
+ return *mainTxtAo;
+ } else if (flowRelation == ELM_ATSPI_RELATION_FLOWS_FROM) {
+ return *acceptAo;
+ }
+ } else if (ao == *mainTxtAo) {
+ if (flowRelation == ELM_ATSPI_RELATION_FLOWS_TO) {
+ return (subTxtAo) ? *subTxtAo : *rejectAo;
+ } else if (flowRelation == ELM_ATSPI_RELATION_FLOWS_FROM) {
+ return *statusTxtAo;
+ }
+ } else if (subTxtAo && ao == *subTxtAo) {
+ if (flowRelation == ELM_ATSPI_RELATION_FLOWS_TO) {
+ return *rejectAo;
+ } else if (flowRelation == ELM_ATSPI_RELATION_FLOWS_FROM) {
+ return *mainTxtAo;
+ }
+ } else if (ao == *rejectAo) {
+ if (flowRelation == ELM_ATSPI_RELATION_FLOWS_TO) {
+ return m_rmCueAo ? *m_rmCueAo : ao;
+ } else if (flowRelation == ELM_ATSPI_RELATION_FLOWS_FROM) {
+ return (subTxtAo) ? *subTxtAo : *mainTxtAo;
+ }
+ } else if (m_rmCueAo && ao == *m_rmCueAo) {
+ if (flowRelation == ELM_ATSPI_RELATION_FLOWS_FROM) {
+ return *rejectAo;
+ }
+ } else if (ao == getWindow()) {
+ return *acceptAo;
+ } else {
+ LOG_RETURN_VALUE(RES_FAIL, nullptr, "Unknown object!");
+ }
+
+ return ao;
+ }
+
+ void MainPage::registerActiveCallModeAo()
+ {
+ DLOG("ENTER");
+ m_atspiHelper->setRelationEventHandler(WEAK_DELEGATE(
+ MainPage::onActiveCallModeAtspiHighlight, asWeak(*this)));
+
+ auto statusTxtAo = m_callInfoPrs->getStatusTxtAo();
+ if (!statusTxtAo) {
+ DLOG("statusTxtAo is NULL");
+ } else {
+ m_atspiHelper->registerWidget(*statusTxtAo);
+ }
+
+ auto mainTxtAo = m_callInfoPrs->getMainTxtAo();
+ if (!mainTxtAo) {
+ DLOG("mainTxtAo is NULL");
+ } else {
+ m_atspiHelper->registerWidget(*mainTxtAo);
+ }
+
+ auto subTxtAo = m_callInfoPrs->getSubTxtAo();
+ if (!subTxtAo) {
+ DLOG("subTxtAo is NULL");
+ } else {
+ m_atspiHelper->registerWidget(*subTxtAo);
+ }
+
+ auto volumeBtnAo = m_accessoryPrs->getVolumBtn();
+ if (!volumeBtnAo) {
+ DLOG("volumeBtnAo is NULL");
+ } else {
+ m_atspiHelper->registerWidget(*volumeBtnAo);
+ }
+
+ auto bluetoothBtnAo = m_accessoryPrs->getBluetoothBtn();
+ if (!bluetoothBtnAo) {
+ DLOG("bluetoothBtnAo is NULL");
+ } else {
+ m_atspiHelper->registerWidget(*bluetoothBtnAo);
+ }
+
+ auto muteBtnAo = m_accessoryPrs->getMuteBtn();
+ if (!muteBtnAo) {
+ DLOG("muteBtnAo is NULL");
+ } else {
+ m_atspiHelper->registerWidget(*muteBtnAo);
+ }
+
+ auto moreOptCueAo = m_moreOptionsPrs->getCueAo();
+ if (!moreOptCueAo) {
+ DLOG("moreCueAo is NULL");
+ } else {
+ m_atspiHelper->registerWidget(*moreOptCueAo);
+ }
+
+ if (!m_bottomBtn) {
+ DLOG("m_bottomBtn is NULL");
+ } else {
+ m_atspiHelper->registerWidget(*m_bottomBtn);
+ }
+
+ auto vcLayout = m_accessoryPrs->getVolumeControlLy();
+ if (!vcLayout) {
+ DLOG("vcLayout is NULL");
+ } else {
+ m_atspiHelper->registerWidget(*vcLayout);
+ }
+
+ auto vcDecrVolumeBtn = m_accessoryPrs->getVolumeControlDecreaseBtn();
+ if (!vcDecrVolumeBtn) {
+ DLOG("vcDecrVolumeBtn is NULL");
+ } else {
+ m_atspiHelper->registerWidget(*vcDecrVolumeBtn);
+ }
+
+ auto vcIncrVolumeBtn = m_accessoryPrs->getVolumeControlIncreaseBtn();
+ if (!vcIncrVolumeBtn) {
+ DLOG("vcIncrVolumeBtn is NULL");
+ } else {
+ m_atspiHelper->registerWidget(*vcIncrVolumeBtn);
+ }
+
+ auto vcVolumeValueAo = m_accessoryPrs->getVolumeControlValueTxtAo();
+ if (!vcVolumeValueAo) {
+ DLOG("vcVolumeValueAo is NULL");
+ } else {
+ m_atspiHelper->registerWidget(*vcVolumeValueAo);
+ }
+
+ DLOG("EXIT");
+ }
+
+ Elm_Interface_Atspi_Accessible *MainPage::onActiveCallModeAtspiHighlight(
+ Elm_Interface_Atspi_Accessible *ao,
+ Elm_Atspi_Relation_Type flowRelation)
+ {
+ DLOG("FlowRelation [%s]",
+ flowRelation == ELM_ATSPI_RELATION_FLOWS_FROM ?
+ "FROM" : "TO");
+
+ auto statusTxtAo = m_callInfoPrs->getStatusTxtAo();
+ auto mainTxtAo = m_callInfoPrs->getMainTxtAo();
+ auto subTxtAo = m_callInfoPrs->getSubTxtAo();
+ auto volumeBtnAo = m_accessoryPrs->getVolumBtn();
+ auto bluetoothBtnAo = m_accessoryPrs->getBluetoothBtn();
+ auto muteBtnAo = m_accessoryPrs->getMuteBtn();
+ auto moreOptCueAo = m_moreOptionsPrs->getCueAo();
+ auto vcLayout = m_accessoryPrs->getVolumeControlLy();
+ auto vcDecrVolumeBtn = m_accessoryPrs->getVolumeControlDecreaseBtn();
+ auto vcIncrVolumeBtn = m_accessoryPrs->getVolumeControlIncreaseBtn();
+ auto vcVolumeValueAo = m_accessoryPrs->getVolumeControlValueTxtAo();
+
+ if (ao == *statusTxtAo) {
+ if (flowRelation == ELM_ATSPI_RELATION_FLOWS_TO) {
+ return *mainTxtAo;
+ }
+ } else if (ao == *mainTxtAo) {
+ if (flowRelation == ELM_ATSPI_RELATION_FLOWS_TO) {
+ if (subTxtAo) {
+ return *subTxtAo;
+ } else {
+ return *volumeBtnAo;
+ }
+ } else {
+ return *statusTxtAo;
+ }
+ } else if (subTxtAo && ao == *subTxtAo) {
+ if (flowRelation == ELM_ATSPI_RELATION_FLOWS_TO) {
+ return *volumeBtnAo;
+ } else {
+ return *mainTxtAo;
+ }
+ } else if (ao == *volumeBtnAo) {
+ if (flowRelation == ELM_ATSPI_RELATION_FLOWS_TO) {
+ return *bluetoothBtnAo;
+ } else {
+ if (subTxtAo) {
+ return *subTxtAo;
+ } else {
+ return *mainTxtAo;
+ }
+ }
+ } else if (ao == *bluetoothBtnAo) {
+ if (flowRelation == ELM_ATSPI_RELATION_FLOWS_TO) {
+ return *muteBtnAo;
+ } else {
+ return *volumeBtnAo;
+ }
+ } else if (ao == *muteBtnAo) {
+ if (flowRelation == ELM_ATSPI_RELATION_FLOWS_TO) {
+ return *moreOptCueAo;
+ } else {
+ return *bluetoothBtnAo;
+ }
+ } else if (ao == *moreOptCueAo) {
+ if (flowRelation == ELM_ATSPI_RELATION_FLOWS_TO) {
+ return *m_bottomBtn;
+ } else {
+ return *muteBtnAo;
+ }
+ } else if (ao == *m_bottomBtn) {
+ if (flowRelation == ELM_ATSPI_RELATION_FLOWS_FROM) {
+ return *moreOptCueAo;
+ }
+ } else if (ao == *vcLayout) {
+ if (flowRelation == ELM_ATSPI_RELATION_FLOWS_TO) {
+ return *vcDecrVolumeBtn;
+ }
+ } else if (ao == *vcDecrVolumeBtn) {
+ if (flowRelation == ELM_ATSPI_RELATION_FLOWS_TO) {
+ return *vcVolumeValueAo;
+ } else {
+ return *vcLayout;
+ }
+ } else if (ao == *vcVolumeValueAo) {
+ if (flowRelation == ELM_ATSPI_RELATION_FLOWS_TO) {
+ return *vcIncrVolumeBtn;
+ } else {
+ return *vcDecrVolumeBtn;
+ }
+ } else if (ao == *vcIncrVolumeBtn) {
+ if (flowRelation == ELM_ATSPI_RELATION_FLOWS_FROM) {
+ return *vcVolumeValueAo;
+ }
+ } else if (ao == getWindow()) {
+ return *statusTxtAo;
+ } else {
+ LOG_RETURN_VALUE(RES_FAIL, nullptr, "Unknown object!");
+ }
+
+ return ao;
+ }
+
+ void MainPage::registerEndCallModeAo()
+ {
+ m_atspiHelper->setRelationEventHandler(WEAK_DELEGATE(
+ MainPage::onEndCallModeAtspiHighlight, asWeak(*this)));
+
+ auto statusTxtAo = m_callInfoPrs->getStatusTxtAo();
+ if (!statusTxtAo) {
+ DLOG("statusTxtAo is NULL");
+ } else {
+ m_atspiHelper->registerWidget(*statusTxtAo);
+ }
+
+ auto mainTxtAo = m_callInfoPrs->getMainTxtAo();
+ if (!mainTxtAo) {
+ DLOG("mainTxtAo is NULL");
+ } else {
+ m_atspiHelper->registerWidget(*mainTxtAo);
+ }
+
+ auto addContactsBtnAo = m_accessoryPrs->getAddContactBtn();
+ if (!addContactsBtnAo) {
+ DLOG("addContactsBtnAo is NULL");
+ } else {
+ m_atspiHelper->registerWidget(*addContactsBtnAo);
+ }
+
+ if (!m_bottomBtn) {
+ DLOG("m_bottomBtn is NULL");
+ } else {
+ m_atspiHelper->registerWidget(*m_bottomBtn);
+ }
+
+ DLOG("EXIT");
+ }
+
+ Elm_Interface_Atspi_Accessible *MainPage::onEndCallModeAtspiHighlight(
+ Elm_Interface_Atspi_Accessible *ao,
+ Elm_Atspi_Relation_Type flowRelation)
+ {
+ DLOG("FlowRelation [%s]",
+ flowRelation == ELM_ATSPI_RELATION_FLOWS_FROM ?
+ "FROM" : "TO");
+
+ auto statusTxtAo = m_callInfoPrs->getStatusTxtAo();
+ auto mainTxtAo = m_callInfoPrs->getMainTxtAo();
+ auto addContactsBtnAo = m_accessoryPrs->getAddContactBtn();
+
+ if (ao == *statusTxtAo) {
+ if (flowRelation == ELM_ATSPI_RELATION_FLOWS_TO) {
+ return *mainTxtAo;
+ }
+ } else if (ao == *mainTxtAo) {
+ if (flowRelation == ELM_ATSPI_RELATION_FLOWS_TO) {
+ if (addContactsBtnAo) {
+ return *addContactsBtnAo;
+ } else {
+ return *m_bottomBtn;
+ }
+ } else {
+ return *statusTxtAo;
+ }
+ } else if (addContactsBtnAo && ao == *addContactsBtnAo) {
+ if (flowRelation == ELM_ATSPI_RELATION_FLOWS_TO) {
+ return *m_bottomBtn;
+ } else {
+ return *mainTxtAo;
+ }
+ } else if (ao == *m_bottomBtn) {
+ if (flowRelation == ELM_ATSPI_RELATION_FLOWS_FROM) {
+ if (addContactsBtnAo) {
+ return *addContactsBtnAo;
+ } else {
+ return *mainTxtAo;
+ }
+ }
+ } else if (ao == getWindow()) {
+ return *statusTxtAo;
+ } else {
+ LOG_RETURN_VALUE(RES_FAIL, nullptr, "Unknown object!");
+ }
+
+ return ao;
+ }
}
#include "model/ISoundManager.h"
#include "presenters/KeypadPage.h"
+#include "presenters/AtspiHighlightHelper.h"
#include "resources.h"
#include "common.h"
constexpr EdjePart PART_SWL_SLOT2 {"swl.slot.2"};
constexpr EdjePart PART_TXT_STATUS {"txt.status"};
+ constexpr EdjePart PART_AO_TXT_STATUS {"ao_txt.status"};
+
+ constexpr EdjePart PART_ACCESS {"access"};
+
constexpr EdjeSignal SIGNAL_ODD {"odd"};
constexpr EdjeSignal SIGNAL_EVEN {"even"};
FAIL_RETURN(createPanelLayout(), "createPanelContent() failed!");
- FAIL_RETURN(createButtons(), "createButtons() failed!");
+ FAIL_RETURN(createAccessObjects(), "createStaticAo() failed!");
- update();
+ updateComponents();
+
+ FAIL_RETURN(createAtspiHighlightHelper(), "createAtspiHighlightHelper() failed!");
deactivateBy(m_widget.get());
return RES_OK;
}
+ void MoreOptionsPresenter::onCueClicked(Evas_Object *obj,
+ const char *emission,
+ const char *source)
+ {
+ show(*m_fakeAo);
+ m_panel->setContent(*m_panelLy);
+ show(*m_panelLy);
+
+ createStatusTxtAo();
+ if (m_statusTxtAo) {
+ m_atspiHelper->registerWidget(*m_statusTxtAo);
+ }
+ }
+
Result MoreOptionsPresenter::createPanel()
{
auto *eo = elm_panel_add(*m_widget);
elm_layout_signal_callback_add(*m_panel, "elm,state,inactive,finished",
"elm", CALLBACK_A(MoreOptionsPresenter::onPanelInactivate), this);
+ setDeactivatorSink(m_panel);
+
+ elm_layout_signal_callback_add(*m_panel, "cue,clicked",
+ "elm", CALLBACK_A(MoreOptionsPresenter::onCueClicked), this);
+
return RES_OK;
}
auto active = m_cm->getActiveCall();
auto held = m_cm->getHeldCall();
+ FAIL_RETURN_VOID(createKeypadButton(),
+ "createKeypadButton() failed");
+
if (held) {
m_panelLy->emit(impl::SIGNAL_EVEN, impl::SIGNAL_SRC_MORE_OPTION);
if (active) {
+ FAIL_RETURN_VOID(createSwapButton(),
+ "createSwapButton() failed");
setPanelContent(*m_btnSwap, impl::PART_SWL_SLOT1);
} else {
+ FAIL_RETURN_VOID(createUnholdButton(),
+ "createUnholdButton() failed");
setPanelContent(*m_btnUnhold, impl::PART_SWL_SLOT1);
}
setPanelContent(*m_btnKeypad, impl::PART_SWL_SLOT2);
}
}
- Result MoreOptionsPresenter::createButtons()
+ Result MoreOptionsPresenter::createSwapButton()
{
- // Swap
m_btnSwap = createButton(impl::STYLE_BTN_SWAP, STR_MORE_SWAP,
WEAK_DELEGATE(MoreOptionsPresenter::onSwapBtnClick,
asWeak(*this)));
LOG_RETURN(RES_FAIL, "Create Swap button failed!");
}
- // Unhold
+ return RES_OK;
+ }
+
+ Result MoreOptionsPresenter::createUnholdButton()
+ {
m_btnUnhold = createButton(impl::STYLE_BTN_UNHOLD, STR_MORE_UNHOLD,
WEAK_DELEGATE(MoreOptionsPresenter::onUnholdBtnClick,
asWeak(*this)));
LOG_RETURN(RES_FAIL, "Create Unhold button failed!");
}
- // Keypad
+ return RES_OK;
+ }
+
+ Result MoreOptionsPresenter::createKeypadButton()
+ {
m_btnKeypad = createButton(impl::STYLE_BTN_KEYPAD, STR_MORE_KEYPAD,
WEAK_DELEGATE(MoreOptionsPresenter::onKeypadBtnClick,
asWeak(*this)));
}
void MoreOptionsPresenter::update()
+ {
+ updateComponents();
+ }
+
+ void MoreOptionsPresenter::updateComponents()
{
updateSlots();
updateStatusText();
const auto keepAliver = asShared(*this);
sendDeactivate(*m_widget);
activateBy(m_widget.get());
+
+ elm_atspi_component_highlight_grab(*m_fakeAo);
}
void MoreOptionsPresenter::onPanelInactivate(Evas_Object *obj,
const auto keepAliver = asShared(*this);
deactivateBy(m_widget.get());
sendActivate(*m_widget);
+
+ m_panel->unsetContent();
+ hide(*m_panelLy);
+ m_statusTxtAo.reset();
+
+ elm_atspi_accessible_can_highlight_set(*m_cueAo, EINA_TRUE);
+ hide(*m_fakeAo);
}
void MoreOptionsPresenter::onBackKey(Evas_Object *obj, void *eventInfo)
}
m_info = info;
m_duration = info->getDuration();
- setCallDuration(m_duration, *m_panelLy, impl::PART_TXT_STATUS);
+ auto temp = getCallDuration(m_duration);
+ m_panelLy->setText(temp, impl::PART_TXT_STATUS);
FAIL_RETURN_VOID(startCallDurationTimer(), "startTimer() failed!");
m_panelLy->setContent(widget, part);
show(widget);
}
+
+ // Screen Reader
+ Result MoreOptionsPresenter::createAtspiHighlightHelper()
+ {
+ DLOG("ENTER");
+ m_atspiHelper = AtspiHighlightHelper::newInstance(*this, getWindow());
+ if (!m_atspiHelper) {
+ LOG_RETURN(RES_FAIL,
+ "AtspiHighlightHelper::newInstance() failed!");
+ }
+
+ m_atspiHelper->setRelationEventHandler(WEAK_DELEGATE(
+ MoreOptionsPresenter::onAtspiHighlight, asWeak(*this)));
+
+ if (m_panelLy) {
+ m_atspiHelper->registerWidget(*m_fakeAo);
+ }
+
+ if (m_panelLy) {
+ m_atspiHelper->registerWidget(*m_panelLy);
+ }
+
+ if (m_btnSwap) {
+ m_atspiHelper->registerWidget(*m_btnSwap);
+ }
+
+ if (m_btnUnhold) {
+ m_atspiHelper->registerWidget(*m_btnUnhold);
+ }
+
+ if (m_btnKeypad) {
+ m_atspiHelper->registerWidget(*m_btnKeypad);
+ }
+
+ if (m_statusTxtAo) {
+ m_atspiHelper->registerWidget(*m_statusTxtAo);
+ }
+ DLOG("EXIT");
+ return RES_OK;
+ }
+
+ Elm_Interface_Atspi_Accessible *MoreOptionsPresenter::onAtspiHighlight(
+ Elm_Interface_Atspi_Accessible *ao,
+ Elm_Atspi_Relation_Type flowRelation)
+ {
+ DLOG("FlowRelation [%s]",
+ flowRelation == ELM_ATSPI_RELATION_FLOWS_FROM ?
+ "FROM" :
+ "TO");
+
+ if (m_btnSwap && ao == *m_btnSwap) {
+ DLOG("Swap button");
+ if (flowRelation == ELM_ATSPI_RELATION_FLOWS_TO) {
+ return *m_btnKeypad;
+ }
+ } else if (m_btnUnhold && ao == *m_btnUnhold) {
+ DLOG("Unhold button");
+ if (flowRelation == ELM_ATSPI_RELATION_FLOWS_TO) {
+ return *m_btnKeypad;
+ }
+ } else if (ao == *m_btnKeypad) {
+ DLOG("Keypad button");
+ if (flowRelation == ELM_ATSPI_RELATION_FLOWS_TO) {
+ return *m_statusTxtAo;
+ } else {
+ if (m_btnSwap) {
+ return *m_btnSwap;
+ } else if (m_btnUnhold) {
+ return *m_btnUnhold;
+ }
+ }
+ } else if (ao == *m_statusTxtAo) {
+ DLOG("Status text");
+ if (flowRelation == ELM_ATSPI_RELATION_FLOWS_FROM) {
+ return *m_btnKeypad;
+ }
+ } else if (ao == getWindow() || ao == *m_fakeAo) {
+ DLOG("window or panelLy");
+ if (m_btnSwap) {
+ return *m_btnSwap;
+ } else if (m_btnUnhold) {
+ return *m_btnUnhold;
+ } else {
+ return *m_btnKeypad;
+ }
+ } else {
+ LOG_RETURN_VALUE(RES_FAIL, nullptr, "Unknown object!");
+ }
+
+ return ao;
+ }
+
+ Result MoreOptionsPresenter::createAccessObjects()
+ {
+ FAIL_RETURN(createCueAo(), "createCueAo() failed");
+ FAIL_RETURN(createStatusTxtAo(), "createStatusTxtAo() failed");
+ FAIL_RETURN(createFakeAo(), "createFakeAo() failed");
+
+ return RES_OK;
+ }
+
+ Result MoreOptionsPresenter::createCueAo()
+ {
+ m_cueAo = utils::createAccessObjectFromLyPart(*m_widget,
+ *m_panel,
+ impl::PART_ACCESS);
+ if (!m_cueAo) {
+ LOG_RETURN(RES_FAIL,
+ "createAccessObjectFromLyPart() failed!");
+ }
+ elm_access_action_cb_set(*m_cueAo,
+ ELM_ACCESS_ACTION_ACTIVATE,
+ CALLBACK_A(MoreOptionsPresenter::onCueAoActionCb),
+ this);
+
+ elm_atspi_accessible_translation_domain_set(*m_cueAo, PACKAGE);
+ elm_atspi_accessible_reading_info_type_set(*m_cueAo,
+ ELM_ACCESSIBLE_READING_INFO_TYPE_NAME |
+ ELM_ACCESSIBLE_READING_INFO_TYPE_ROLE);
+ elm_atspi_accessible_name_set(*m_cueAo, AO_STR_MORE_OPTIONS);
+ elm_atspi_accessible_role_set(*m_cueAo, ELM_ATSPI_ROLE_PUSH_BUTTON);
+
+ return RES_OK;
+ }
+
+ ElmWidget *MoreOptionsPresenter::getCueAo()
+ {
+ return m_cueAo.get();
+ }
+
+ Result MoreOptionsPresenter::createFakeAo()
+ {
+ m_fakeAo = utils::createFakeAccessObject(*m_panel);
+ if (!m_fakeAo) {
+ LOG_RETURN(RES_FAIL, "createFakeAccessObject() failed!");
+ }
+
+ return RES_OK;
+ }
+
+ Result MoreOptionsPresenter::createStatusTxtAo()
+ {
+ m_statusTxtAo = utils::createAccessObjectFromLyPart(*m_widget,
+ *m_panelLy,
+ impl::PART_AO_TXT_STATUS);
+ if (!m_statusTxtAo) {
+ LOG_RETURN(RES_FAIL,
+ "createAccessObjectFromLyPart() failed!");
+ }
+
+ elm_atspi_accessible_reading_info_type_set(*m_statusTxtAo,
+ ELM_ACCESSIBLE_READING_INFO_TYPE_NAME);
+ elm_atspi_accessible_name_cb_set(*m_statusTxtAo,
+ [](void *data, Evas_Object *obj) -> char *
+ {
+ auto self = static_cast<MoreOptionsPresenter *>(data);
+ if (!self) {
+ return nullptr;
+ }
+ auto txt = self->m_panelLy->
+ getText(impl::PART_TXT_STATUS).getCStr();
+ return (txt) ? strdup(txt) : nullptr;
+ },
+ this);
+
+ return RES_OK;
+ }
+
+ Eina_Bool MoreOptionsPresenter::onCueAoActionCb(Evas_Object *obj,
+ Elm_Access_Action_Info *actionInfo)
+ {
+ switch (actionInfo->action_type) {
+ case ELM_ACCESS_ACTION_ACTIVATE:
+
+ show(*m_fakeAo);
+ m_panel->setContent(*m_panelLy);
+ show(*m_panelLy);
+ createStatusTxtAo();
+ if (m_statusTxtAo) {
+ m_atspiHelper->registerWidget(*m_statusTxtAo);
+ }
+
+ elm_panel_toggle(*m_panel);
+ elm_atspi_component_highlight_clear(*m_cueAo);
+ elm_atspi_accessible_can_highlight_set(*m_cueAo, EINA_FALSE);
+
+ return EINA_TRUE;
+ break;
+ default:
+ break;
+ }
+
+ return EINA_FALSE;
+ }
}
#include "model/IRejectMsgProvider.h"
#include "model/IRejectMsg.h"
+#include "presenters/AtspiHighlightHelper.h"
+
#include "resources.h"
#include "common.h"
FAIL_RETURN(createPanelLy(),
"createPanelLy() failed!");
- FAIL_RETURN(createGenlist(),
- "createGenlist() failed!");
+ FAIL_RETURN(createAtspiHighlightHelper(),
+ "createScreenReaderRoute() failed!");
deactivateBy(m_widget.get());
{
Elm_Panel_Scroll_Info *ev = static_cast<Elm_Panel_Scroll_Info *>(eventInfo);
DLOG("pos x[%f] y[%f]", ev->rel_x, ev->rel_y);
+ auto prevState = m_state;
if (ev->rel_y == 1.0) {
m_state = RejectMsgState::SHOWN;
// Prevent panel scrolling
elm_object_scroll_freeze_push(m_panel->getEo());
- sendDeactivate(*m_widget);
- activateBy(m_widget.get());
} else if (ev->rel_y == 0.0) {
m_state = RejectMsgState::HIDDEN;
- // Scroll genlist to top
- elm_scroller_region_show(m_genlist->getEo(), 0, 0, 0, 0);
+ m_genlist.reset();
} else {
+ if (!m_genlist) {
+ FAIL_RETURN_VOID(createGenlist(),
+ "createGenlist() failed!");
+ }
+
m_state = RejectMsgState::IN_TRANSITION;
const auto alphaValue =
static_cast<int>(impl::ALPHA_CHANNEL_MAX * ev->rel_y);
m_panelBg->setColor(0, alphaValue);
- if (isActive()) {
+ }
+
+ if (prevState != m_state) {
+ if (m_state == RejectMsgState::SHOWN) {
+ activateBy(m_widget.get());
+ } else {
deactivateBy(m_widget.get());
+ }
+
+ if (m_state == RejectMsgState::HIDDEN) {
sendActivate(*m_widget);
+ } else {
+ sendDeactivate(*m_widget);
}
- }
- if (m_stateHandler) {
- m_stateHandler(m_state);
+ if (m_stateHandler) {
+ m_stateHandler(m_state);
+ }
}
}
m_widget->setContent(*m_panel, impl::PART_SWL_RIGHT);
+ setDeactivatorSink(m_panel);
+
return RES_OK;
}
LOG_RETURN(RES_FAIL, "Layout::build failed!");
}
// Circular surface
- Eext_Circle_Surface *const circleSurf = eext_circle_surface_layout_add(*circlLy);
+ Eext_Circle_Surface *const circleSurf =
+ eext_circle_surface_layout_add(*circlLy);
if (!circleSurf) {
LOG_RETURN(RES_FAIL, "eext_circle_surface_layout_add() failed!");
}
if (!glEo) {
LOG_RETURN(RES_FAIL, "elm_genlist_add() failed!");
}
- evas_object_size_hint_weight_set(glEo, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
- evas_object_size_hint_align_set(glEo, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_genlist_mode_set(glEo, ELM_LIST_COMPRESS);
elm_genlist_homogeneous_set(glEo, EINA_TRUE);
- m_genlist = makeShared<StyledWidget>(glEo);
- m_circleEo = eext_circle_object_genlist_add(m_genlist->getEo(), circleSurf);
+ m_genlist = makeShared<StyledWidget>(glEo, true);
+ m_genlist->setWeight(EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ m_genlist->setAlign(EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+ m_circleEo = eext_circle_object_genlist_add(m_genlist->getEo(),
+ circleSurf);
if (!m_circleEo) {
LOG_RETURN(RES_FAIL, "elm_genlist_add() failed!");
}
- eext_circle_object_genlist_scroller_policy_set(m_circleEo, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_AUTO);
+ eext_circle_object_genlist_scroller_policy_set(m_circleEo,
+ ELM_SCROLLER_POLICY_OFF,
+ ELM_SCROLLER_POLICY_AUTO);
deactivateRotary();
FAIL_RETURN(fillGenlist(), "fillGenlist() failed!");
m_panelLy->setContent(*m_genlist, impl::PART_SWL_CONTENT);
+ registerGenlistAtspiGestureCallbacks();
+
return RES_OK;
}
Result RejectMsgPresenter::addGenlistTitleItem()
{
- static auto titleItc = createGenlistItemClass("title",
+ static auto titleItc = utils::createGenlistItemClass("title",
[](void *data, Evas_Object *obj, const char *part) -> char * {
return strdup(STR_DECLINE_MESSAGES.translate());
});
Result RejectMsgPresenter::addGenlistTextItem(const IRejectMsgSRef &rm)
{
- static auto textItc = createGenlistItemClass("1text.1icon",
+ static auto textItc = utils::createGenlistItemClass("1text.1icon",
[](void *data, Evas_Object *obj, const char *part) -> char * {
if (!data) {
LOG_RETURN_VALUE(RES_FAIL, nullptr, "Data is NULL");
Result RejectMsgPresenter::addGenlistBottomItem()
{
- static auto paddingItc = createGenlistItemClass("1text.1icon");
+ static auto paddingItc = utils::createGenlistItemClass("1text.1icon");
auto *item = elm_genlist_item_append(*m_genlist, &paddingItc,
nullptr,
return m_state;
}
+ void RejectMsgPresenter::showPanel()
+ {
+ DLOG();
+ if (m_state != RejectMsgState::SHOWN) {
+ DLOG("Panel state [NOT SHOWN]");
+ elm_panel_hidden_set(m_panel->getEo(), EINA_FALSE);
+ }
+ }
+
void RejectMsgPresenter::hidePanel()
{
DLOG();
}
}
+ // Screen Reader
+ Elm_Interface_Atspi_Accessible *RejectMsgPresenter::getFirstAo()
+ {
+ return (m_genlist) ?
+ elm_genlist_first_item_get(*m_genlist) :
+ nullptr;
+ }
+
+ Elm_Interface_Atspi_Accessible *RejectMsgPresenter::getLastAo()
+ {
+ return (m_genlist) ?
+ elm_genlist_last_item_get(*m_genlist) :
+ nullptr;
+ }
+
+ Result RejectMsgPresenter::createAtspiHighlightHelper()
+ {
+ m_atspiHelper = AtspiHighlightHelper::newInstance(*this, getWindow());
+ if (!m_atspiHelper) {
+ LOG_RETURN(RES_FAIL, "AtspiHighlightHelper::newInstance() failed!");
+ }
+
+ m_atspiHelper->setRelationEventHandler(WEAK_DELEGATE(
+ RejectMsgPresenter::onAtspiHighlight, asWeak(*this)));
+
+ return RES_OK;
+ }
+
+ void RejectMsgPresenter::registerGenlistAtspiGestureCallbacks()
+ {
+ auto item = getFirstAo();
+ elm_atspi_accessible_gesture_cb_set(item,
+ CALLBACK_A(RejectMsgPresenter::onAtspiGesture), this);
+
+ item = getLastAo();
+ elm_atspi_accessible_gesture_cb_set(item,
+ CALLBACK_A(RejectMsgPresenter::onAtspiGesture), this);
+ }
+
+ Elm_Interface_Atspi_Accessible *RejectMsgPresenter::onAtspiHighlight(
+ Elm_Interface_Atspi_Accessible *ao,
+ Elm_Atspi_Relation_Type flowRelation)
+ {
+ DLOG("ENTER");
+
+ DLOG("FlowRelation [%s]",
+ flowRelation == ELM_ATSPI_RELATION_FLOWS_FROM ?
+ "FROM" :
+ "TO");
+
+ if (ao == getFirstAo()) {
+ if (flowRelation == ELM_ATSPI_RELATION_FLOWS_TO) {
+ return nullptr;
+ }
+ } else if (ao == getLastAo()) {
+ if (flowRelation == ELM_ATSPI_RELATION_FLOWS_FROM) {
+ return nullptr;
+ }
+ } else if (ao == getWindow()) {
+ return getFirstAo();
+ } else {
+ LOG_RETURN_VALUE(RES_FAIL, nullptr, "Unknown object!");
+ }
+ return ao;
+ }
+
+ Eina_Bool RejectMsgPresenter::onAtspiGesture(
+ Elm_Atspi_Gesture_Info gestureInfo,
+ Elm_Interface_Atspi_Accessible *ao)
+ {
+ return toEina(
+ m_atspiHelper->handleGesture(ao, gestureInfo));
+ }
}
namespace callui {
constexpr auto CALL_VC_TIMER_INTERVAL = 1.5;
+ constexpr auto CALL_VC_SCREEN_READER_TIMER_INTERVAL = 5.0;
constexpr auto VOLUME_LEVEL_MIN = 1;
}
}
}
- void setCallDuration(const struct tm &time,
- EdjeWidget &widget,
- const EdjePart &part)
+ TString getCallDuration(const struct tm &time)
{
TString tmp;
if (time.tm_hour > 0) {
} else {
tmp = himpl::STR_MM_SS_TIME.format(time.tm_min, time.tm_sec);
}
- widget.setText(tmp, part);
+ return tmp;
}
void tryUpdateCallDurationTime(
{
if ((compTime.tm_sec - curTime.tm_sec) != 0) {
curTime = compTime;
- setCallDuration(curTime, widget, part);
+ auto tmp = getCallDuration(curTime);
+ widget.setText(tmp, part);
}
}
void replaceSubstringInString(std::string &str,
const std::string &from, const std::string &to);
- void setCallDuration(const struct tm &time,
- ucl::EdjeWidget &widget, const ucl::EdjePart &part);
+ ucl::TString getCallDuration(const struct tm &time);
void tryUpdateCallDurationTime(
struct tm &curTime, struct tm &compTime,
const ucl::TString STR_MORE_HOLD {"Hold"};
const ucl::TString STR_MORE_UNHOLD {"Unhold"};
const ucl::TString STR_MORE_GEAR {"Gear"};
+
+ // Screen Reader
+ const ucl::TString AO_STR_CALL {"Call"};
+ const ucl::TString AO_STR_VOLUME {"Volume"};
+ const ucl::TString AO_STR_HEADSET {"Headset"};
+ const ucl::TString AO_STR_GEAR_SPK {"Gear speaker"};
+ const ucl::TString AO_STR_MUTE {"Mute"};
+ const ucl::TString AO_STR_MORE_OPTIONS {"More options"};
+ const ucl::TString AO_STR_END_CALL {"End call"};
+ const ucl::TString AO_STR_CALLBACK {"Callback"};
+ const ucl::TString AO_STR_ADD_TO_CONTACTS {"Add to contacts"};
+ const ucl::TString AO_STR_ROTATE_BEZEL_TO_ADJUST {"Rotate bezel to adjust"};
+ const ucl::TString AO_STR_DECREASE_VOLUME {"Decrease volume"};
+ const ucl::TString AO_STR_INCREASE_VOLUME {"Increase volume"};
+ const ucl::TString AO_STR_ACCEPT_CALL {"Accept call"};
+ const ucl::TString AO_STR_SWIPE_RIGHT_WITH_TWO_FINGERS_TO_ACCEPT
+ {"Swipe right with two fingers to accept"};
+ const ucl::TString AO_STR_REJECT_CALL {"Reject call"};
+ const ucl::TString AO_STR_SWIPE_LEFT_WITH_TWO_FINGERS_TO_REJECT
+ {"Swipe left with two fingers to reject"};
+ const ucl::TString AO_STR_DECLINE_MESSAGES {"Decline messages"};
+ const ucl::TString AO_STR_SWIPE_UP_WITH_TWO_FINGERS_TO_SEND_A_DECLINE_MESSAGE
+ {"Swipe up with two fingers to send a decline message"};
}
#include "view/AcceptRejectWidget.h"
#include "common.h"
+#include "resources.h"
#define CU_COL_TRANSPARENT 0, 0, 0, 0
#define CU_COL_WHITE 255, 255, 255, 255
auto result = makeShared<AcceptRejectWidget>(layout,
m_acceptHandler, m_rejectHandler, m_acceptBtnType);
+ FAIL_RETURN_VALUE(result->registerAccessObjects(parent), {},
+ "registerScreenReaderObjects() failed!");
+
result->bindToEo();
return result;
setRejectUnpressedTransitions();
}
+
+ // Screen Reader
+ ElmWidget *AcceptRejectWidget::getAcceptAo()
+ {
+ return m_accAo.get();
+ }
+
+ ElmWidget *AcceptRejectWidget::getRejectAo()
+ {
+ return m_rejAo.get();
+ }
+
+ Result AcceptRejectWidget::registerAccessObjects(ElmWidget &parent)
+ {
+ m_accAo = utils::createAccessObject(parent, *m_accEventLy);
+ if (!m_accAo) {
+ LOG_RETURN(RES_FAIL, "createAccessObject() failed!");
+ }
+ elm_atspi_accessible_translation_domain_set(*m_accAo, PACKAGE);
+ elm_atspi_accessible_reading_info_type_set(*m_accAo,
+ ELM_ACCESSIBLE_READING_INFO_TYPE_NAME |
+ ELM_ACCESSIBLE_READING_INFO_TYPE_DESCRIPTION);
+ elm_atspi_accessible_name_set(*m_accAo, AO_STR_ACCEPT_CALL);
+ elm_atspi_accessible_description_set(*m_accAo,
+ AO_STR_SWIPE_RIGHT_WITH_TWO_FINGERS_TO_ACCEPT);
+
+ m_rejAo = utils::createAccessObject(parent, *m_rejEventLy);
+ if (!m_rejAo) {
+ LOG_RETURN(RES_FAIL, "createAccessObject() failed!");
+ }
+ elm_atspi_accessible_translation_domain_set(*m_rejAo, PACKAGE);
+ elm_atspi_accessible_reading_info_type_set(*m_rejAo,
+ ELM_ACCESSIBLE_READING_INFO_TYPE_NAME |
+ ELM_ACCESSIBLE_READING_INFO_TYPE_DESCRIPTION);
+ elm_atspi_accessible_name_set(*m_rejAo, AO_STR_REJECT_CALL);
+ elm_atspi_accessible_description_set(*m_rejAo,
+ AO_STR_SWIPE_LEFT_WITH_TWO_FINGERS_TO_REJECT);
+
+ return RES_OK;
+ }
+
}
{
m_layout->setIsOwner(false);
- evas_object_size_hint_align_set(m_slider,
- EVAS_HINT_FILL, EVAS_HINT_FILL);
- evas_object_size_hint_weight_set(m_slider,
- EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ m_slider.setAlign(EVAS_HINT_FILL, EVAS_HINT_FILL);
+ m_slider.setWeight(EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
m_layout->setContent(m_circleLy, impl::PART_SWL_SLIDER);
show(m_circleLy);
setMaxValue(maxValue);
setValue(curValue);
+
+ // Screen Reader
+ elm_atspi_accessible_role_set(m_slider,
+ ELM_ATSPI_ROLE_REDUNDANT_OBJECT);
+ elm_atspi_accessible_role_set(m_circleLy,
+ ELM_ATSPI_ROLE_REDUNDANT_OBJECT);
+ elm_atspi_accessible_role_set(*m_layout,
+ ELM_ATSPI_ROLE_REDUNDANT_OBJECT);
}
void Slider::setValue(int value)
#include "view/VolumeControl.h"
#include "common.h"
+#include "resources.h"
namespace callui { namespace { namespace impl {
constexpr EdjePart PART_TXT_INFO {"txt.info"};
constexpr EdjePart PART_TXT_VALUE {"txt.value"};
+ constexpr EdjePart PART_TXT_VALUE_AO {"ao_txt.value"};
}}}
{
}
- void VolumeControl::prepare(const ucl::TString &info, int curValue)
+ void VolumeControl::prepare(const TString &info, int curValue)
{
+ m_layout->addEventHandler(WidgetEvent::SHOW, WEAK_DELEGATE(
+ VolumeControl::onWidgetShowCb, asWeak(*this)));
+ m_layout->addEventHandler(WidgetEvent::HIDE, WEAK_DELEGATE(
+ VolumeControl::onWidgetHideCb, asWeak(*this)));
+
m_decreaseBtn.setStyle(impl::STYLE_BTN_MINUS);
m_decreaseBtn.addEventHandler(BTN_CLICKED, WEAK_DELEGATE(
VolumeControl::onDecreaseBtnClickedCb, asWeak(*this)));
setInfoText(info);
setValue(curValue);
+
+ registerAccessObjectInformation();
+ }
+
+ void VolumeControl::onWidgetShowCb(Widget &widget, void *eventInfo)
+ {
+ if (m_valueTxtAo)
+ show(*m_valueTxtAo);
+ }
+
+ void VolumeControl::onWidgetHideCb(Widget &widget, void *eventInfo)
+ {
+ if (m_valueTxtAo)
+ hide(*m_valueTxtAo);
}
void VolumeControl::setInfoText(const TString &info)
}
}
+ // Screen Reader
+ ElmWidget *VolumeControl::getDecreaseBtn()
+ {
+ return &m_decreaseBtn;
+ }
+
+ ElmWidget *VolumeControl::getIncreaseBtn()
+ {
+ return &m_increaseBtn;
+ }
+
+ ElmWidget *VolumeControl::getValueTxtAo()
+ {
+ return m_valueTxtAo.get();
+ }
+
+ void VolumeControl::registerAccessObjectInformation()
+ {
+ elm_atspi_accessible_translation_domain_set(m_slider, PACKAGE);
+ elm_atspi_accessible_reading_info_type_set(m_slider,
+ ELM_ACCESSIBLE_READING_INFO_TYPE_NAME
+ | ELM_ACCESSIBLE_READING_INFO_TYPE_DESCRIPTION);
+ elm_atspi_accessible_name_set(m_slider, AO_STR_VOLUME);
+ elm_atspi_accessible_description_set(m_slider,
+ AO_STR_ROTATE_BEZEL_TO_ADJUST);
+
+ elm_atspi_accessible_translation_domain_set(m_decreaseBtn, PACKAGE);
+ elm_atspi_accessible_name_set(m_decreaseBtn,
+ AO_STR_DECREASE_VOLUME);
+
+ elm_atspi_accessible_translation_domain_set(m_increaseBtn, PACKAGE);
+ elm_atspi_accessible_name_set(m_increaseBtn,
+ AO_STR_INCREASE_VOLUME);
+
+ m_valueTxtAo = utils::createAccessObjectFromLyPart(
+ *m_layout,
+ *m_layout,
+ impl::PART_TXT_VALUE_AO);
+ if (!m_valueTxtAo) {
+ ELOG("createAccessObjectFromLyPart() failed");
+ } else {
+ elm_atspi_accessible_translation_domain_set(*m_valueTxtAo,
+ PACKAGE);
+ elm_atspi_accessible_reading_info_type_set(*m_valueTxtAo,
+ ELM_ACCESSIBLE_READING_INFO_TYPE_NAME);
+ elm_atspi_accessible_name_cb_set(*m_valueTxtAo,
+ [](void *data, Evas_Object *obj) -> char *
+ {
+ auto self = static_cast<VolumeControl *>(data);
+ if (!self) {
+ return nullptr;
+ }
+ auto txt = self->m_layout->
+ getText(impl::PART_TXT_VALUE).getCStr();
+ return (txt) ? strdup(txt) : nullptr;
+ },
+ this);
+ }
+
+ elm_atspi_accessible_role_set(*m_layout, ELM_ATSPI_ROLE_TEXT);
+ }
}
#include "ucl/gui/Window.h"
#include "ucl/gui/Naviframe.h"
+#include "ucl/gui/Layout.h"
#include "common.h"
using namespace ucl;
constexpr EoDataKey CIRCLE_SURFACE {"callui,eext,circle,surface"};
+
+ constexpr LayoutTheme LAYOUT_FAKE_ACCESS_OBJECT
+ {"layout", "callui", "fake_access_object"};
}}}
-namespace callui {
+namespace callui { namespace utils {
using namespace ucl;
return sfc;
}
- void addRotaryEventHandler(Eext_Rotary_Handler_Cb func, void *data)
- {
- eext_rotary_event_handler_add(func, data);
- }
-
- void delRotaryEventHandler(Eext_Rotary_Handler_Cb func, void *data)
+ ElmWidgetSRef createFakeAccessObject(ElmWidget &parent)
{
- std::vector<void *> backup;
- while (true) {
- void *const oldData = eext_rotary_event_handler_del(func);
- if (!oldData || (oldData == data)) {
- return;
- }
- backup.push_back(oldData);
- }
- for (auto i = backup.size(); i-- > 0; ) {
- eext_rotary_event_handler_add(func, backup[i]);
+ const auto result = Layout::Builder().
+ setTheme(impl::LAYOUT_FAKE_ACCESS_OBJECT).
+ setIsOwner(true).
+ setNeedBindToEo(true).
+ build(parent);
+ if (!result) {
+ LOG_RETURN_VALUE(RES_FAIL, {}, "Layout::build() failed!");
}
+
+ result->setGeometry(0, 0, 1, 1);
+ show(*result);
+
+ elm_atspi_accessible_reading_info_type_set(*result, 0);
+
+ elm_atspi_accessible_gesture_cb_set(*result,
+ [](void *, Elm_Atspi_Gesture_Info, Evas_Object *) -> Eina_Bool
+ {
+ return EINA_TRUE;
+ },
+ nullptr);
+
+ return result;
}
+
Elm_Genlist_Item_Class createGenlistItemClass(const char *style,
Elm_Gen_Item_Text_Get_Cb txtCb,
Elm_Gen_Item_Content_Get_Cb contentCb,
return itc;
}
+ ElmWidgetSRef createAccessObject(ElmWidget &parent, Widget &ly)
+ {
+ auto ao = elm_access_object_register(ly, parent);
+ if (!ao) {
+ LOG_RETURN_VALUE(RES_FAIL, {},
+ "elm_access_object_register() failed!");
+ }
+
+ return makeShared<ElmWidget>(ao, true);
+ }
+
+ ElmWidgetSRef createAccessObjectFromLyPart(ElmWidget &parent,
+ Widget &ly,
+ const EdjePart &lyPart)
+ {
+ auto po = const_cast<Evas_Object *>(
+ edje_object_part_object_get(
+ elm_layout_edje_get(ly), lyPart));
+ if (!po) {
+ LOG_RETURN_VALUE(RES_FAIL, {}, "Part object is NULL");
+ }
+
+ auto ao = elm_access_object_register(po, parent);
+ if (!ao) {
+ LOG_RETURN_VALUE(RES_FAIL, {},
+ "elm_access_object_register() failed!");
+ }
+
+ return makeShared<ElmWidget>(ao, true);
+ }
+
+ void destroyAccessObject(ElmWidget &ao)
+ {
+ elm_access_object_unregister(ao);
+ }
+
+}}
+
+namespace callui {
+
+ void addRotaryEventHandler(Eext_Rotary_Handler_Cb func, void *data)
+ {
+ eext_rotary_event_handler_add(func, data);
+ }
+
+ void delRotaryEventHandler(Eext_Rotary_Handler_Cb func, void *data)
+ {
+ std::vector<void *> backup;
+ while (true) {
+ void *const oldData = eext_rotary_event_handler_del(func);
+ if (!oldData || (oldData == data)) {
+ break;
+ }
+ backup.push_back(oldData);
+ }
+ for (auto i = backup.size(); i-- > 0; ) {
+ eext_rotary_event_handler_add(func, backup[i]);
+ }
+ }
+
LayoutTheme getImageTheme(const char *const fileName)
{
return {"layout", "callui_image", fileName};
}
+ Elm_Atspi_Relation_Type getFlowRelation(Elm_Atspi_Gesture_Info gestureInfo)
+ {
+ switch (gestureInfo.type) {
+ case ELM_ATSPI_GESTURE_ONE_FINGER_FLICK_RIGHT:
+ case ELM_ATSPI_GESTURE_ONE_FINGER_FLICK_DOWN:
+ return ELM_ATSPI_RELATION_FLOWS_TO;
+ case ELM_ATSPI_GESTURE_ONE_FINGER_FLICK_LEFT:
+ case ELM_ATSPI_GESTURE_ONE_FINGER_FLICK_UP:
+ return ELM_ATSPI_RELATION_FLOWS_FROM;
+ default:
+ break;
+ }
+ return ELM_ATSPI_RELATION_NULL;
+ }
+
}