TizenRefApp-8454 [Call UI] Implement AcceptRejectPresenter & TizenRefApp-8455 [Call... 67/127667/2
authorIgor Olshevskyi <i.olshevskyi@samsung.com>
Fri, 28 Apr 2017 07:42:08 +0000 (10:42 +0300)
committerIgor Olshevskyi <i.olshevskyi@samsung.com>
Mon, 15 May 2017 05:43:58 +0000 (08:43 +0300)
Change-Id: I0948d647de5393ec02474f12f266e5c59ab923e8

25 files changed:
.cproject
edc/buttons.edc [new file with mode: 0644]
edc/color_classes.edc [new file with mode: 0644]
edc/images/call_button_bg_accept_reject_press.png [new file with mode: 0644]
edc/images/w_call_incoming_icon_accept.png [new file with mode: 0644]
edc/images/w_call_incoming_icon_reject.png [new file with mode: 0644]
edc/layouts.edc [new file with mode: 0644]
inc/model/ICallManager.h
inc/presenters/AcceptDialog.h [new file with mode: 0644]
inc/presenters/AcceptRejectPresenter.h [new file with mode: 0644]
inc/presenters/MainPage.h
inc/presenters/types.h
inc/resources.h
inc/view/helpers.h
inc/view/types.h [new file with mode: 0644]
res/edje/theme.edc
src/model/CallManager.cpp
src/model/CallManager.h
src/presenters/AcceptDialog.cpp [new file with mode: 0644]
src/presenters/AcceptRejectPresenter.cpp [new file with mode: 0644]
src/presenters/MainPage.cpp
src/resources.cpp [new file with mode: 0644]
src/view/common.h
src/view/helpers.cpp
ucl/inc/ucl/util/types/classTypes.h

index 7809432a0a5e3abf4f9fd2721c366582a62d2a09..c3ce0872704bd4b94799751a53e0c95b9865f372 100644 (file)
--- a/.cproject
+++ b/.cproject
                                                                        <listOptionValue builtIn="false" value="Native_API"/>
                                                                </option>
                                                                <option id="gnu.cpp.compiler.option.dialect.std.2098907038" name="Language standard" superClass="gnu.cpp.compiler.option.dialect.std" value="gnu.cpp.compiler.dialect.c++11" valueType="enumerated"/>
-                                                               <option id="sbi.gnu.cpp.compiler.option.preprocessor.def.deprecation.1401781788" superClass="sbi.gnu.cpp.compiler.option.preprocessor.def.deprecation" valueType="definedSymbols">
+                                                               <option id="sbi.gnu.cpp.compiler.option.preprocessor.def.deprecation.1401781788" name="Defined symbols (-D)" superClass="sbi.gnu.cpp.compiler.option.preprocessor.def.deprecation" valueType="definedSymbols">
                                                                        <listOptionValue builtIn="false" value="TIZEN_DEPRECATION"/>
                                                                        <listOptionValue builtIn="false" value="DEPRECATION_WARNING"/>
                                                                        <listOptionValue builtIn="false" value="_DEBUG"/>
                                                                        <listOptionValue builtIn="false" value="Native_API"/>
                                                                </option>
                                                                <option id="gnu.c.compiler.option.dialect.std.1743559858" name="Language standard" superClass="gnu.c.compiler.option.dialect.std" value="gnu.c.compiler.dialect.default" valueType="enumerated"/>
-                                                               <option id="sbi.gnu.c.compiler.option.preprocessor.def.symbols.deprecation.958464226" superClass="sbi.gnu.c.compiler.option.preprocessor.def.symbols.deprecation" valueType="definedSymbols">
+                                                               <option id="sbi.gnu.c.compiler.option.preprocessor.def.symbols.deprecation.958464226" name="Defined symbols (-D)" superClass="sbi.gnu.c.compiler.option.preprocessor.def.symbols.deprecation" valueType="definedSymbols">
                                                                        <listOptionValue builtIn="false" value="TIZEN_DEPRECATION"/>
                                                                        <listOptionValue builtIn="false" value="DEPRECATION_WARNING"/>
                                                                        <listOptionValue builtIn="false" value="_DEBUG"/>
                                                        <tool id="org.tizen.nativecore.tool.ast.cpp.2059548129" name="C++ Static Analyzer" superClass="org.tizen.nativecore.tool.ast.cpp"/>
                                                        <tool id="org.tizen.nativecore.tool.sbi.gnu.archiver.mergelib.1347531198" name="Archive Generator" superClass="org.tizen.nativecore.tool.sbi.gnu.archiver.mergelib"/>
                                                        <tool id="org.tizen.nativecore.tool.sbi.po.compiler.1000732861" name="PO Resource Compiler" superClass="org.tizen.nativecore.tool.sbi.po.compiler"/>
-                                                       <tool id="org.tizen.nativecore.tool.sbi.edc.compiler.692187818" name="EDC Resource Compiler" superClass="org.tizen.nativecore.tool.sbi.edc.compiler"/>
+                                                       <tool id="org.tizen.nativecore.tool.sbi.edc.compiler.692187818" name="EDC Resource Compiler" superClass="org.tizen.nativecore.tool.sbi.edc.compiler">
+                                                               <option id="sbi.gnu.edc.compiler.option.misc.id.434887912" superClass="sbi.gnu.edc.compiler.option.misc.id" valueType="stringList">
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/edc/images&quot;"/>
+                                                               </option>
+                                                       </tool>
                                                </toolChain>
                                        </folderInfo>
                                        <sourceEntries>
diff --git a/edc/buttons.edc b/edc/buttons.edc
new file mode 100644 (file)
index 0000000..776ae02
--- /dev/null
@@ -0,0 +1,252 @@
+/*
+ * 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.
+ */
+
+#define CU_BTN_ANIM_TIME       0.15
+#define CU_BTN_UNPRESS_DELAY   0.6
+
+#define CU_BTN_ICON_WH         54
+#define CU_BTN_EFFECT_START_WH 100
+#define CU_BTN_EFFECT_END_WH   130
+
+#define INCOMING_CALL_BTN(_name, _icon, _bg_cc, _effect_cc, _icon_norm_cc, _icon_pressed_cc) \
+group { "elm/button/base/"_name; \
+       script { \
+               public is_pressed; \
+               public is_expanded; \
+               public unpress_timer; \
+               public press(bool:auto_unpress) \
+               { \
+                       cancel_timer(get_int(unpress_timer)); \
+                       set_int(unpress_timer, 0); \
+                       if (get_int(is_pressed) == 0) { \
+                               set_int(is_pressed, 1); \
+                               run_program(PROGRAM:"pressed"); \
+                               emit("elm,action,press", ""); \
+                       } \
+                       if (auto_unpress) { \
+                               set_int(unpress_timer, timer(CU_BTN_UNPRESS_DELAY, "unpress", 0)); \
+                       } \
+               } \
+               public unpress() \
+               { \
+                       if (get_int(is_pressed) == 1 && get_int(is_expanded) == 0) { \
+                               set_int(is_pressed, 0); \
+                               run_program(PROGRAM:"unpressed"); \
+                               emit("elm,action,unpress", ""); \
+                       } \
+               } \
+               public expand() \
+               { \
+                       if (get_int(is_pressed) == 1 && get_int(is_expanded) == 0) { \
+                               set_int(is_expanded, 1); \
+                               run_program(PROGRAM:"expanded"); \
+                               timer(CU_BTN_ANIM_TIME + 0.1, "click", 0); \
+                       } \
+               } \
+               public click() \
+               { \
+                       emit("elm,action,click", ""); \
+               } \
+               public iabs(x) \
+               { \
+                       return x > 0 ? x : -x; \
+               } \
+       } \
+       images.image: "call_button_bg_accept_reject_press.png" COMP; \
+       images.image: _icon COMP; \
+       parts { \
+               image { "image.border"; \
+                       scale; \
+                       desc { "default"; \
+                               fixed: 1 1; \
+                               rel1.relative: 0.5 0.5; \
+                               rel2.relative: 0.5 0.5; \
+                               image.normal: "call_button_bg_accept_reject_press.png"; \
+                               color_class: _bg_cc; \
+                       } \
+                       desc { "pressed_effect"; \
+                               inherit: "default"; \
+                               min: CU_BTN_EFFECT_START_WH CU_BTN_EFFECT_START_WH; \
+                       } \
+                       desc { "pressed"; \
+                               inherit: "pressed_effect"; \
+                               min: CU_BTN_EFFECT_END_WH CU_BTN_EFFECT_END_WH; \
+                       } \
+                       desc { "expanded"; \
+                               inherit: "pressed"; \
+                               rel1.relative: 0.0 0.0; \
+                               rel2.relative: 1.0 1.0; \
+                       } \
+               } \
+               image { "image.effect"; \
+                       inherit: "image.border"; \
+                       before: "image.border"; \
+                       desc { "default"; \
+                               color_class: _effect_cc; \
+                       } \
+                       desc { "pressed_effect"; \
+                               color_class: _effect_cc; \
+                       } \
+                       desc { "pressed"; \
+                               inherit: "expanded"; \
+                               color_class: _effect_cc; \
+                       } \
+               } \
+               image { "icon"; \
+                       scale; \
+                       clip: "rect.icon_bg"; \
+                       desc { "default"; \
+                               fixed: 1 1; \
+                               min: CU_BTN_ICON_WH CU_BTN_ICON_WH; \
+                               rel1.relative: 0.5 0.5; \
+                               rel2.relative: 0.5 0.5; \
+                               image.normal: _icon; \
+                       } \
+               } \
+               rect { "rect.icon_bg"; \
+                       desc { "default"; \
+                               color_class: _icon_norm_cc; \
+                       } \
+                       desc { "pressed"; \
+                               color_class: _icon_pressed_cc; \
+                       } \
+               } \
+               rect { "rect.event"; \
+                       desc { "default"; \
+                               fixed: 1 1; \
+                               min: CU_BTN_EFFECT_START_WH CU_BTN_EFFECT_START_WH; \
+                               rel1.relative: 0.5 0.5; \
+                               rel2.relative: 0.5 0.5; \
+                               color: 0 0 0 0; \
+                       } \
+               } \
+       } \
+       programs { \
+               program { \
+                       signal: "mouse,down,*"; \
+                       source: "rect.event"; \
+                       script { \
+                               press(false); \
+                       } \
+               } \
+               program { \
+                       signal: "mouse,up,*"; \
+                       source: "rect.event"; \
+                       script { \
+                               unpress(); \
+                       } \
+               } \
+               program { \
+                       signal: "press"; \
+                       source: "*"; \
+                       script { \
+                               if (get_int(is_pressed) == 0) { \
+                                       press(true); \
+                               } else { \
+                                       expand(); \
+                               } \
+                       } \
+               } \
+               program { \
+                       signal: "reset"; \
+                       source: "*"; \
+                       action: STATE_SET "default"; \
+                       script { \
+                               set_int(is_pressed, 0); \
+                               set_int(is_expanded, 0); \
+                               cancel_timer(get_int(unpress_timer)); \
+                               run_program(PROGRAM:"reset_state"); \
+                       } \
+               } \
+               program { \
+                       signal: "unpress"; \
+                       source: "*"; \
+                       script { \
+                               unpress(); \
+                       } \
+               } \
+               program { \
+                       name: "pressed"; \
+                       sequence { \
+                               action: STATE_SET "pressed_effect"; \
+                               targets: "image.effect" "image.border"; \
+                               action: STATE_SET "pressed"; \
+                               targets: "image.effect" "image.border" "rect.icon_bg"; \
+                               transition: TRANSITION_GLIDE(CU_BTN_ANIM_TIME); \
+                       } \
+               } \
+               program { \
+                       name: "unpressed"; \
+                       sequence { \
+                               action: STATE_SET "default"; \
+                               targets: "image.border" "rect.icon_bg"; \
+                               action: STATE_SET "pressed_effect"; \
+                               target: "image.effect"; \
+                               transition: TRANSITION_GLIDE(CU_BTN_ANIM_TIME); \
+                               action: STATE_SET "default"; \
+                               target: "image.effect"; \
+                       } \
+               } \
+               program { \
+                       name: "reset_state"; \
+                       sequence { \
+                               action: STATE_SET "default"; \
+                               targets: "image.border" "rect.icon_bg"; \
+                               action: STATE_SET "pressed_effect"; \
+                               target: "image.effect"; \
+                               action: STATE_SET "default"; \
+                               target: "image.effect"; \
+                       } \
+               } \
+               program { \
+                       name: "expanded"; \
+                       action: STATE_SET "expanded"; \
+                       target: "image.border"; \
+                       transition: TRANSITION_GLIDE(CU_BTN_ANIM_TIME); \
+               } \
+               program { \
+                       signal: "mouse,move"; \
+                       source: "rect.event"; \
+                       script { \
+                               if (get_int(is_pressed) == 0 || get_int(is_expanded) == 1) { \
+                                       return; \
+                               } \
+                               new mx, my; \
+                               get_mouse(mx, my); \
+                               new x, y, w, h; \
+                               get_geometry(PART:"image.border", x, y, w, h); \
+                               x = iabs(mx - (x + w / 2)); \
+                               y = iabs(my - (y + h / 2)); \
+                               new Float:d = sqrt(x * x + y * y) * 2; \
+                               get_geometry(PART:"image.effect", x, y, w, h); \
+                               if (d >= w) { \
+                                       expand(); \
+                               } else if (d <= CU_BTN_EFFECT_END_WH) { \
+                                       set_state(PART:"image.border", "pressed", 0.0); \
+                               } else { \
+                                       new Float:rel = ((w - d) / w) / 2; \
+                                       custom_state(PART:"image.border", "pressed", 0.0); \
+                                       set_state_val(PART:"image.border", STATE_REL1, rel, rel); \
+                                       set_state_val(PART:"image.border", STATE_REL2, 1.0 - rel, 1.0 - rel); \
+                                       set_state(PART:"image.border", "custom", 0.0); \
+                               } \
+                       } \
+               } \
+       } \
+}
+
+INCOMING_CALL_BTN("callui/accept", "w_call_incoming_icon_accept.png", "AO01131", "AO01132", "AO0113", "AO0113P")
+INCOMING_CALL_BTN("callui/reject", "w_call_incoming_icon_reject.png", "AO01151", "AO01152", "AO0115", "AO0115P")
diff --git a/edc/color_classes.edc b/edc/color_classes.edc
new file mode 100644 (file)
index 0000000..66b3fb2
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+color_classes {
+       color_class { name: "AO0115";
+               color: 222 11 0 255;
+       }
+       color_class { name: "AO0115P";
+               color: 255 255 255 255;
+       }
+       color_class { name: "AO01151";
+               color: 222 11 0 175;
+       }
+       color_class { name: "AO01152";
+               color: 222 11 0 77;
+       }
+       color_class { name: "AO0113";
+               color: 77 185 39 255;
+       }
+       color_class { name: "AO0113P";
+               color: 255 255 255 255;
+       }
+       color_class { name: "AO01131";
+               color: 97 237 50 175;
+       }
+       color_class { name: "AO01132";
+               color: 97 237 50 77;
+       }
+}
diff --git a/edc/images/call_button_bg_accept_reject_press.png b/edc/images/call_button_bg_accept_reject_press.png
new file mode 100644 (file)
index 0000000..646baa9
Binary files /dev/null and b/edc/images/call_button_bg_accept_reject_press.png differ
diff --git a/edc/images/w_call_incoming_icon_accept.png b/edc/images/w_call_incoming_icon_accept.png
new file mode 100644 (file)
index 0000000..ae4b0e4
Binary files /dev/null and b/edc/images/w_call_incoming_icon_accept.png differ
diff --git a/edc/images/w_call_incoming_icon_reject.png b/edc/images/w_call_incoming_icon_reject.png
new file mode 100644 (file)
index 0000000..cb15dfd
Binary files /dev/null and b/edc/images/w_call_incoming_icon_reject.png differ
diff --git a/edc/layouts.edc b/edc/layouts.edc
new file mode 100644 (file)
index 0000000..ad93a14
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * 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.
+ */
+
+#define CU_BTN_PADDING_LR 13
+#define CU_BTN_WH         54
+#define CU_BTN_FULL_WH    480
+
+#define CU_BTN_HIDE_ANIM_TIME  0.2
+
+group { "elm/layout/callui/main";
+       parts {
+               swallow { "swl.accept_reject";
+                       scale;
+                       desc { "default";
+                       }
+               }
+       }
+}
+
+group { "elm/layout/callui/incoming_call";
+       parts {
+               spacer { "spacer.left";
+                       scale;
+                       desc { "default";
+                               fixed: 1 0;
+                               align: 1.0 0.5;
+                               rel2.relative: 0.0 1.0;
+                       }
+                       desc { "hidden";
+                               inherit: "default";
+                               min: (CU_BTN_PADDING_LR+CU_BTN_WH) 0;
+                       }
+               }
+               spacer { "spacer.right";
+                       scale;
+                       desc { "default";
+                               fixed: 1 0;
+                               align: 0.0 0.5;
+                               rel1.relative: 1.0 0.0;
+                       }
+                       desc { "hidden";
+                               inherit: "default";
+                               min: (CU_BTN_PADDING_LR+CU_BTN_WH) 0;
+                       }
+               }
+               spacer { "spacer.reject.left";
+                       scale;
+                       desc { "default";
+                               fixed: 1 0;
+                               min: (CU_BTN_PADDING_LR+CU_BTN_WH/2) 0;
+                               align: 0.0 0.5;
+                               rel1 { relative: 0.0 0.0; to_x: "spacer.left"; }
+                               rel2 { relative: 0.0 1.0; to_x: "spacer.left"; }
+                       }
+               }
+               swallow { "swl.button_accept";
+                       scale;
+                       desc { "default";
+                               fixed: 1 1;
+                               min: CU_BTN_FULL_WH CU_BTN_FULL_WH;
+                               rel1 { relative: 1.0 0.5; to_x: "spacer.reject.left"; }
+                               rel2 { relative: 1.0 0.5; to_x: "spacer.reject.left"; }
+                       }
+               }
+               spacer { "spacer.accept.right";
+                       scale;
+                       desc { "default";
+                               fixed: 1 0;
+                               min: (CU_BTN_PADDING_LR+CU_BTN_WH/2) 0;
+                               align: 1.0 0.5;
+                               rel1 { relative: 1.0 0.0; to_x: "spacer.right"; }
+                               rel2 { relative: 1.0 1.0; to_x: "spacer.right"; }
+                       }
+               }
+               swallow { "swl.button_reject";
+                       scale;
+                       desc { "default";
+                               fixed: 1 1;
+                               min: CU_BTN_FULL_WH CU_BTN_FULL_WH;
+                               rel1 { relative: 0.0 0.5; to_x: "spacer.accept.right"; }
+                               rel2 { relative: 0.0 0.5; to_x: "spacer.accept.right"; }
+                       }
+               }
+       }
+       programs {
+               program {
+                       signal: "accept,show";
+                       source: "*";
+                       action: STATE_SET "default";
+                       target: "spacer.left";
+                       transition: TRANSITION_GLIDE(CU_BTN_HIDE_ANIM_TIME);
+               }
+               program {
+                       signal: "accept,hide";
+                       source: "*";
+                       action: STATE_SET "hidden";
+                       target: "spacer.left";
+                       transition: TRANSITION_GLIDE(CU_BTN_HIDE_ANIM_TIME);
+               }
+               program {
+                       signal: "reject,show";
+                       source: "*";
+                       action: STATE_SET "default";
+                       target: "spacer.right";
+                       transition: TRANSITION_GLIDE(CU_BTN_HIDE_ANIM_TIME);
+               }
+               program {
+                       signal: "reject,hide";
+                       source: "*";
+                       action: STATE_SET "hidden";
+                       target: "spacer.right";
+                       transition: TRANSITION_GLIDE(CU_BTN_HIDE_ANIM_TIME);
+               }
+               program {
+                       signal: "reset";
+                       source: "*";
+                       action: STATE_SET "default";
+                       targets: "spacer.right" "spacer.left";
+               }
+       }
+
+}
\ No newline at end of file
index 89afd9150285df08f7b6de912c2458a71496f471..6fbcaa616372556504aaecc65a21a9c676ab4fcd 100644 (file)
@@ -23,10 +23,10 @@ namespace callui {
 
        class ICallManager : public ucl::Polymorphic {
        public:
-               virtual IIncomingCallWRef getIncomingCall() = 0;
-               virtual IActiveCallWRef getActiveCall() = 0;
-               virtual IHeldCallWRef getHeldCall() = 0;
-               virtual IEndCallWRef getEndCall() = 0;
+               virtual IIncomingCallSRef getIncomingCall() = 0;
+               virtual IActiveCallSRef getActiveCall() = 0;
+               virtual IHeldCallSRef getHeldCall() = 0;
+               virtual IEndCallSRef getEndCall() = 0;
                virtual CallMask getAvailableCalls() const = 0;
        };
 }
diff --git a/inc/presenters/AcceptDialog.h b/inc/presenters/AcceptDialog.h
new file mode 100644 (file)
index 0000000..8319efe
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * 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_VIEW_ACCEPT_DIALOG_H__
+#define __CALLUI_VIEW_ACCEPT_DIALOG_H__
+
+#include "ucl/gui/StyledWidget.h"
+#include "ucl/gui/ElmWidget.h"
+
+#include "types.h"
+
+namespace callui {
+
+       class AcceptDialog final :
+                       public ucl::RefCountAware,
+                       public ucl::IDisposable {
+       public:
+               class Builder {
+               public:
+                       Builder();
+                       ~Builder();
+                       Builder &setHandler(AcceptDialogHandler handler);
+                       AcceptDialogWRef build(ucl::ElmWidget &parent) const;
+               private:
+                       AcceptDialogHandler m_handler;
+               };
+
+       public:
+               virtual ~AcceptDialog();
+
+               void dismiss();
+
+               // ucl::IDisposable
+
+               virtual void dispose() final override;
+               virtual bool isDisposed() const final override;
+
+       private:
+               friend class ucl::RefCountObj<AcceptDialog>;
+               AcceptDialog(ucl::RefCountObjBase &rc,
+                               const AcceptDialogHandler &handler);
+
+               ucl::Result prepare(ucl::ElmWidget &parent);
+
+               ucl::Result createPopup(ucl::ElmWidget &parent, ucl::ElmStyle style);
+               ucl::Result createGenlist();
+               ucl::Result fillGenlist();
+               ucl::Result addGenlistTitleItem();
+               ucl::Result addGenlistTextItem(AcceptDialogEvent event);
+               ucl::Result addGenlistBottomItem();
+
+               void handleEvent(AcceptDialogEvent event);
+               bool dispatchEvent(AcceptDialogEvent event);
+
+               void onPopupDismissed(ucl::Widget &widget, void *eventInfo);
+               void onPopupHWBackKey(Evas_Object *obj, void *eventInfo);
+
+               void onGenlistItemClickedCb(Evas_Object *obj, void *event_info);
+
+       private:
+               ucl::StyledWidgetSRef m_popup;
+               ucl::StyledWidgetSRef m_genlist;
+               AcceptDialogHandler m_handler;
+               bool m_isDismissed;
+       };
+
+}
+
+#endif // __CALLUI_VIEW_ACCEPT_DIALOG_H__
diff --git a/inc/presenters/AcceptRejectPresenter.h b/inc/presenters/AcceptRejectPresenter.h
new file mode 100644 (file)
index 0000000..194ebe6
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * 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_ACCEPT_REJECT_PRESENTER_H__
+#define __CALLUI_PRESENTERS_ACCEPT_REJECT_PRESENTER_H__
+
+#include "ucl/gui/Layout.h"
+#include "ucl/gui/StyledWidget.h"
+
+#include "types.h"
+
+namespace callui {
+
+       class AcceptRejectPresenter final : public ucl::RefCountAware {
+       public:
+               class Builder {
+               public:
+                       Builder();
+                       ~Builder();
+                       Builder &setIncomingCall(const IIncomingCallSRef &call);
+                       Builder &setAvailableCallsFlag(CallMask calls);
+                       AcceptRejectPresenterSRef build(ucl::ElmWidget &parent) const;
+
+               private:
+                       IIncomingCallSRef m_call;
+                       CallMask m_callMask;
+               };
+
+       public:
+               virtual ~AcceptRejectPresenter();
+
+               ucl::Widget &getWidget();
+
+               void update(CallMask calls);
+
+       private:
+               friend class ucl::RefCountObj<AcceptRejectPresenter>;
+               AcceptRejectPresenter(ucl::RefCountObjBase &rc,
+                               const IIncomingCallSRef &call,
+                               CallMask calls);
+
+               ucl::Result prepare(ucl::Widget &parent);
+
+               ucl::Result createWidget(ucl::Widget &parent);
+               ucl::Result createAcceptBtn();
+               ucl::Result createRejectBtn();
+
+               ucl::StyledWidgetSRef createBtn(const ucl::ElmStyle &style,
+                               const ucl::EdjePart &part);
+               void showPopup();
+
+               void processAccept();
+               void processReject() const;
+
+               void onBtnPressed(ucl::Widget &widget, void *eventInfo);
+               void onBtnUnpressed(ucl::Widget &widget, void *eventInfo);
+               void onBtnClicked(ucl::Widget &widget, void *eventInfo);
+
+               Eina_Bool onRotaryEvent(Eext_Rotary_Event_Info *info);
+
+               bool onAcceptPopupEvent(AcceptDialog &popup, AcceptDialogEvent event);
+
+       private:
+               ucl::LayoutSRef m_widget;
+               AcceptDialogWRef m_popup;
+               ucl::StyledWidgetSRef m_accept;
+               ucl::StyledWidgetSRef m_reject;
+
+               IIncomingCallSRef m_call;
+               CallMask m_callMask;
+       };
+}
+
+
+
+#endif // __CALLUI_PRESENTERS_ACCEPT_REJECT_PRESENTER_H__
index fb160361ce2a5dc8727ca851fccc6ebcc3daa532..27d973e0796e2c9ba66137523c11ea6ece9788c2 100644 (file)
@@ -20,6 +20,8 @@
 #include "Page.h"
 #include "model/ICallListener.h"
 
+#include "ucl/gui/Layout.h"
+
 #include "types.h"
 
 namespace callui {
@@ -48,6 +50,8 @@ namespace callui {
 
                ucl::Result prepare();
 
+               ucl::Result createAcceptRejectPresenter();
+
                // Page
 
                virtual void onBackKey() final override;
@@ -58,7 +62,9 @@ namespace callui {
                virtual void onError(CallErr err) final override;
 
        private:
+               ucl::LayoutSRef m_widget;
                ICallSRef m_call;
+               AcceptRejectPresenterSRef m_acceptReject;
        };
 }
 
index c7d19e38f284a04d4c263eae8e337cd66d8ec227..65bf1881fa8d9a20547711d7f14c85d10788ff8d 100644 (file)
 
 #include "../types.h"
 
+#include "view/types.h"
 #include "model/types.h"
 
 namespace callui {
 
-       UCL_DECLARE_REF_ALIASES(Page);
+       enum class AcceptDialogEvent {
+               HOLD_AND_ACCEPT,
+               END_AND_ACCEPT,
+               BACK
+       };
 
+       UCL_DECLARE_REF_ALIASES(Page);
        UCL_DECLARE_REF_ALIASES(MainPage);
+
+       UCL_DECLARE_REF_ALIASES(AcceptRejectPresenter);
+       UCL_DECLARE_REF_ALIASES(AcceptDialog);
+
+       using AcceptDialogHandler = ucl::WeakDelegate<bool(AcceptDialog &, AcceptDialogEvent)>;
 }
 
 #endif // __CALLUI_PRESENTERS_TYPES_H__
index b75cd5707635a4e1ca32260c213ec4fc11c0a2fc..513594252a8c0fafd437e69b2ee3a1eee2574b39 100644 (file)
 namespace callui {
 
        constexpr auto THEME_EDJE_PATH = "edje/theme.edj";
+
+       extern const ucl::TString STR_ANSWER_CALL;
+       extern const ucl::TString STR_HOLD_AND_ACCEPT;
+       extern const ucl::TString STR_END_AND_ACCEPT;
 }
 
 #endif // __CALLUI_RESOURCES_H__
index 75ab4c8050883b217aeffdc0e82e1f3f039bc3be..e830901c7ddda269d1f2979bd3e70da1842abf85 100644 (file)
@@ -33,6 +33,15 @@ namespace callui {
 
        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);
+
+       Elm_Genlist_Item_Class createGenlistItemClass(const char *style,
+                       Elm_Gen_Item_Text_Get_Cb txtCb = nullptr,
+                       Elm_Gen_Item_Content_Get_Cb contentCb = nullptr,
+                       Elm_Gen_Item_State_Get_Cb stateCb = nullptr,
+                       Elm_Gen_Item_Del_Cb delCb = nullptr);
 }
 
 #endif // __CALLUI_VIEW_HELPERS_H__
diff --git a/inc/view/types.h b/inc/view/types.h
new file mode 100644 (file)
index 0000000..4ff7915
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * 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_VIEW_TYPES_H__
+#define __CALLUI_VIEW_TYPES_H__
+
+#include <efl_extension.h>
+
+#include "ucl/gui/types.h"
+
+#include "../types.h"
+
+#endif // __CALLUI_VIEW_TYPES_H__
index 84af94201c1a533a2355fd3ab194b273ff234b09..1d768dc9fedcbbf60357acc6d39607e273c062ae 100644 (file)
  * limitations under the License.
  */
 
+#define TRANSITION_GLIDE(duration) CUBIC_BEZIER (duration) 0.25 0.46 0.45 1.0
+
 collections {
-   base_scale: 1.3;
+       base_scale: 1.3;
 
-   plugins {
-      plugin {
-         name: "touch_sound";
-         source: "feedback";
-         param: "FEEDBACK_TYPE_SOUND FEEDBACK_PATTERN_TAP";
-      }
-   }
+       plugins {
+               plugin {
+                       name: "touch_sound";
+                       source: "feedback";
+                       param: "FEEDBACK_TYPE_SOUND FEEDBACK_PATTERN_TAP";
+               }
+       }
 
+       #include "../../edc/color_classes.edc"
+       #include "../../edc/layouts.edc"
+       #include "../../edc/buttons.edc"
 }
index 2ad118c862a3055636b8a2477aec9f4bd2741a1e..0df997e7fa5462134e624fdb32ce74286fba20b8 100644 (file)
@@ -119,22 +119,22 @@ namespace callui {
                return m_slot;
        }
 
-       IIncomingCallWRef CallManager::getIncomingCall()
+       IIncomingCallSRef CallManager::getIncomingCall()
        {
                return m_incomingCall;
        }
 
-       IActiveCallWRef CallManager::getActiveCall()
+       IActiveCallSRef CallManager::getActiveCall()
        {
                return m_activeCall;
        }
 
-       IHeldCallWRef CallManager::getHeldCall()
+       IHeldCallSRef CallManager::getHeldCall()
        {
                return m_heldCall;
        }
 
-       IEndCallWRef CallManager::getEndCall()
+       IEndCallSRef CallManager::getEndCall()
        {
                return m_endCall;
        }
index a2ce29b0306ab96c8606b5dbc7a8ee107b0ee05e..583c05c54b508c52b5ac40edfbe69542344f2d69 100644 (file)
@@ -46,10 +46,10 @@ namespace callui {
 
                // ICallManager
 
-               virtual IIncomingCallWRef getIncomingCall() override final;
-               virtual IActiveCallWRef getActiveCall() override final;
-               virtual IHeldCallWRef getHeldCall() override final;
-               virtual IEndCallWRef getEndCall() override final;
+               virtual IIncomingCallSRef getIncomingCall() override final;
+               virtual IActiveCallSRef getActiveCall() override final;
+               virtual IHeldCallSRef getHeldCall() override final;
+               virtual IEndCallSRef getEndCall() override final;
                virtual CallMask getAvailableCalls() const override final;
 
        private:
diff --git a/src/presenters/AcceptDialog.cpp b/src/presenters/AcceptDialog.cpp
new file mode 100644 (file)
index 0000000..2c7de25
--- /dev/null
@@ -0,0 +1,286 @@
+/*
+ * 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/AcceptDialog.h"
+
+#include "resources.h"
+#include "common.h"
+
+namespace callui { namespace { namespace impl {
+
+       using namespace ucl;
+
+       constexpr ElmStyle POPUP_STYLE {"circle"};
+
+       constexpr SmartEvent POPUP_DISMISSED {"dismissed"};
+
+       void *asData(const AcceptDialogEvent event)
+       {
+               return reinterpret_cast<void *>(static_cast<intptr_t>(event));
+       }
+
+       AcceptDialogEvent asEvent(void *const data)
+       {
+               return static_cast<AcceptDialogEvent>(
+                               reinterpret_cast<intptr_t>(data));
+       }
+
+}}}
+
+namespace callui {
+
+       using namespace ucl;
+
+       AcceptDialog::Builder::Builder()
+       {
+       }
+
+       AcceptDialog::Builder::~Builder()
+       {
+       }
+
+       AcceptDialog::Builder &AcceptDialog::Builder::setHandler(AcceptDialogHandler handler)
+       {
+               m_handler = handler;
+               return *this;
+       }
+
+       AcceptDialogWRef AcceptDialog::Builder::build(ElmWidget &parent) const
+       {
+               if (!m_handler) {
+                       LOG_RETURN_VALUE(RES_INVALID_ARGUMENTS, {}, "m_handler is NULL");
+               }
+
+               auto result = makeShared<AcceptDialog>(m_handler);
+               FAIL_RETURN_VALUE(result->prepare(parent), {},
+                               "result->prepare() failed!");
+
+               return result;
+       }
+
+       AcceptDialog::AcceptDialog(RefCountObjBase &rc,
+                       const AcceptDialogHandler &handler):
+                                       RefCountAware(&rc),
+                                       m_handler(handler),
+                                       m_isDismissed(false)
+       {
+       }
+
+       AcceptDialog::~AcceptDialog()
+       {
+       }
+
+       Result AcceptDialog::prepare(ElmWidget &parent)
+       {
+               FAIL_RETURN(createPopup(parent, impl::POPUP_STYLE),
+                               "createPopup() failed!");
+
+               FAIL_RETURN(createGenlist(),
+                               "createGenlist() failed!");
+
+               m_rc->ref();
+
+               return RES_OK;
+       }
+
+       Result AcceptDialog::createPopup(ElmWidget &parent, ElmStyle style)
+       {
+               Evas_Object *const popupEo = elm_popup_add(parent);
+               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);
+
+               show(*m_popup);
+
+               m_popup->addEventHandler(impl::POPUP_DISMISSED, WEAK_DELEGATE(
+                               AcceptDialog::onPopupDismissed, asWeak(*this)));
+
+               eext_object_event_callback_add(*m_popup, EEXT_CALLBACK_BACK,
+                               CALLBACK_A(AcceptDialog::onPopupHWBackKey), this);
+
+               return RES_OK;
+       }
+
+       void AcceptDialog::onGenlistItemClickedCb(Evas_Object *obj, void *event_info)
+       {
+               if (!event_info)
+                       LOG_RETURN_VOID(RES_FAIL, "event_info is NULL");
+
+               Elm_Object_Item *item = static_cast<Elm_Object_Item *>(event_info);
+               handleEvent(impl::asEvent(elm_object_item_data_get(item)));
+       }
+
+       Result AcceptDialog::createGenlist()
+       {
+               Evas_Object *const glEo = elm_genlist_add(*m_popup);
+               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);
+
+               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);
+               eext_rotary_object_event_activated_set(circleGlEo, EINA_TRUE);
+
+               FAIL_RETURN(fillGenlist(), "fillGenlist() failed!");
+
+               EdjePart content{"elm.swallow.content"};
+               m_popup->setContent(glEo, content);
+
+               return RES_OK;
+       }
+
+       Result AcceptDialog::addGenlistTitleItem()
+       {
+               static Elm_Genlist_Item_Class titleItc = createGenlistItemClass("title",
+                               [](void *data, Evas_Object *obj, const char *part) -> char * {
+                                       return strdup(STR_ANSWER_CALL.translate());
+                               });
+
+               Elm_Object_Item *item = elm_genlist_item_append(*m_genlist, &titleItc,
+                               nullptr,
+                               nullptr,
+                               ELM_GENLIST_ITEM_NONE,
+                               nullptr,
+                               nullptr);
+               if (!item)
+                       LOG_RETURN(RES_FAIL, "elm_genlist_item_append() failed!");
+
+               return RES_OK;
+       }
+
+       Result AcceptDialog::addGenlistTextItem(AcceptDialogEvent event)
+       {
+               static Elm_Genlist_Item_Class textItc = createGenlistItemClass("1text.1icon",
+                               [](void *data, Evas_Object *obj, const char *part) -> char * {
+                                       switch (impl::asEvent(data)) {
+                                       case AcceptDialogEvent::HOLD_AND_ACCEPT:
+                                               return strdup(STR_HOLD_AND_ACCEPT.translate());
+                                       case AcceptDialogEvent::END_AND_ACCEPT:
+                                               return strdup(STR_END_AND_ACCEPT.translate());
+                                       default:
+                                               return nullptr;
+                                       }
+                               });
+
+               Elm_Object_Item *item = elm_genlist_item_append(*m_genlist, &textItc,
+                               impl::asData(event),
+                               nullptr,
+                               ELM_GENLIST_ITEM_NONE,
+                               CALLBACK_A(AcceptDialog::onGenlistItemClickedCb),
+                               this);
+               if (!item)
+                       LOG_RETURN(RES_FAIL, "elm_genlist_item_append() failed!");
+
+               return RES_OK;
+       }
+
+       Result AcceptDialog::addGenlistBottomItem()
+       {
+               static Elm_Genlist_Item_Class paddingItc = createGenlistItemClass("1text.1icon");
+
+               Elm_Object_Item *item = elm_genlist_item_append(*m_genlist, &paddingItc,
+                               nullptr,
+                               nullptr,
+                               ELM_GENLIST_ITEM_NONE,
+                               nullptr,
+                               nullptr);
+               if (!item)
+                       LOG_RETURN(RES_FAIL, "elm_genlist_item_append() failed!");
+
+               return RES_OK;
+       }
+
+
+       Result AcceptDialog::fillGenlist()
+       {
+               FAIL_RETURN(addGenlistTitleItem(), "addGenlistTitleItem() failed!");
+
+               FAIL_RETURN(addGenlistTextItem(AcceptDialogEvent::HOLD_AND_ACCEPT),
+                               "addGenlistTextItem() failed!");
+
+               FAIL_RETURN(addGenlistTextItem(AcceptDialogEvent::END_AND_ACCEPT),
+                               "addGenlistTextItem() failed!");
+
+               FAIL_RETURN(addGenlistBottomItem(), "addGenlistBottomItem() failed!");
+
+               return RES_OK;
+       }
+
+       void AcceptDialog::handleEvent(AcceptDialogEvent event)
+       {
+               const auto keepAliver = asShared(*this);
+               if (dispatchEvent(event)) {
+                       dismiss();
+               }
+       }
+
+       bool AcceptDialog::dispatchEvent(AcceptDialogEvent event)
+       {
+               if (!m_handler) {
+                       WLOG("Handler was destroyed!");
+                       return true;
+               }
+               return m_handler(*this, event);
+       }
+
+       void AcceptDialog::onPopupDismissed(ucl::Widget &widget, void *eventInfo)
+       {
+               dispose();
+       }
+
+       void AcceptDialog::onPopupHWBackKey(Evas_Object *obj, void *eventInfo)
+       {
+               if (!m_isDismissed) {
+                       handleEvent(AcceptDialogEvent::BACK);
+               }
+       }
+
+       void AcceptDialog::dismiss()
+       {
+               if (m_popup && !m_isDismissed) {
+                       m_isDismissed = true;
+                       elm_popup_dismiss(*m_popup);
+               }
+       }
+
+       void AcceptDialog::dispose()
+       {
+               if (m_popup) {
+
+                       eext_object_event_callback_del(*m_popup, EEXT_CALLBACK_BACK,
+                                       CALLBACK_A(AcceptDialog::onPopupHWBackKey));
+
+                       m_popup.reset();
+
+                       m_rc->unref();
+               }
+       }
+
+       bool AcceptDialog::isDisposed() const
+       {
+               return (!m_popup);
+       }
+}
diff --git a/src/presenters/AcceptRejectPresenter.cpp b/src/presenters/AcceptRejectPresenter.cpp
new file mode 100644 (file)
index 0000000..f51c06b
--- /dev/null
@@ -0,0 +1,300 @@
+/*
+ * 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/AcceptRejectPresenter.h"
+
+#include "model/IIncomingCall.h"
+#include "presenters/AcceptDialog.h"
+
+#include "../view/common.h"
+#include "common.h"
+
+namespace callui { namespace { namespace impl {
+
+       using namespace ucl;
+
+       constexpr LayoutTheme LAYOUT_INCOMING_CALL_WIDGET
+                       {"layout", "callui", "incoming_call"};
+
+       constexpr EdjeSignal SIGNAL_ACCEEPT_SHOW {"accept,show"};
+       constexpr EdjeSignal SIGNAL_ACCEEPT_HIDE {"accept,hide"};
+       constexpr EdjeSignal SIGNAL_REJECT_SHOW {"reject,show"};
+       constexpr EdjeSignal SIGNAL_REJECT_HIDE {"reject,hide"};
+
+       constexpr EdjeSignal SIGNAL_RESET {"reset"};
+
+       constexpr EdjePart PART_SWL_BTN_ACCEPT {"swl.button_accept"};
+       constexpr EdjePart PART_SWL_BTN_REJECT {"swl.button_reject"};
+
+       constexpr EdjeSignal SIGNAL_BTN_PRESS {"press"};
+       constexpr EdjeSignal SIGNAL_BTN_UNPRESS {"unpress"};
+
+       constexpr ElmStyle STYLE_BTN_ACCEPT {"callui/accept"};
+       constexpr ElmStyle STYLE_BTN_REJECT {"callui/reject"};
+
+       constexpr SmartEvent EVENT_PRESSED {"pressed"};
+       constexpr SmartEvent EVENT_UNPRESSED {"unpressed"};
+
+}}}
+
+namespace callui {
+
+       using namespace ucl;
+
+       // IncomingCallPresenter::Builder
+
+       AcceptRejectPresenter::Builder::Builder():
+                       m_callMask(0)
+       {
+       }
+
+       AcceptRejectPresenter::Builder::~Builder()
+       {
+       }
+
+       AcceptRejectPresenter::Builder &AcceptRejectPresenter::Builder::setIncomingCall(const IIncomingCallSRef &call)
+       {
+               m_call = call;
+               return *this;
+       }
+
+       AcceptRejectPresenter::Builder &AcceptRejectPresenter::Builder::setAvailableCallsFlag(CallMask mask)
+       {
+               m_callMask = mask;
+               return *this;
+       }
+
+       AcceptRejectPresenterSRef AcceptRejectPresenter::Builder::build(ElmWidget &parent) const
+       {
+               auto result = makeShared<AcceptRejectPresenter>(m_call, m_callMask);
+               FAIL_RETURN_VALUE(result->prepare(parent), {}, "result->prepare() failed!");
+               return result;
+       }
+
+       // IncomingCallPresenter
+
+       AcceptRejectPresenter::AcceptRejectPresenter(RefCountObjBase &rc,
+                       const IIncomingCallSRef &call,
+                       CallMask calls):
+                       RefCountAware(&rc),
+                       m_call(call),
+                       m_callMask(calls)
+       {
+       }
+
+       AcceptRejectPresenter::~AcceptRejectPresenter()
+       {
+               if (m_popup) {
+                       m_popup->dispose();
+               }
+
+               eext_rotary_object_event_activated_set(m_widget->getEo(), EINA_FALSE);
+
+               delRotaryEventHandler(CALLBACK_A(
+                               AcceptRejectPresenter::onRotaryEvent), this);
+       }
+
+       Result AcceptRejectPresenter::prepare(Widget &parent)
+       {
+               FAIL_RETURN(createWidget(parent), "createWidget() failed!");
+
+               FAIL_RETURN(createAcceptBtn(), "createAcceptBtn() failed!");
+
+               FAIL_RETURN(createRejectBtn(), "createRejectBtn() failed!");
+
+               addRotaryEventHandler(CALLBACK_A(
+                               AcceptRejectPresenter::onRotaryEvent), this);
+
+               eext_rotary_object_event_activated_set(m_widget->getEo(), EINA_TRUE);
+
+               return RES_OK;
+       }
+
+       Widget &AcceptRejectPresenter::getWidget()
+       {
+               return *m_widget;
+       }
+
+       void AcceptRejectPresenter::update(CallMask calls)
+       {
+               if (m_callMask != calls) {
+                       m_callMask = calls;
+                       if (m_popup) {
+                               m_accept->emit(impl::SIGNAL_RESET);
+                               m_widget->emit(impl::SIGNAL_RESET);
+                               m_popup->dismiss();
+                       }
+               }
+       }
+
+       Result AcceptRejectPresenter::createWidget(Widget &parent)
+       {
+               m_widget = Layout::Builder().
+                               setTheme(impl::LAYOUT_INCOMING_CALL_WIDGET).
+                               setIsOwner(true).
+                               build(parent);
+               if (!m_widget) {
+                       LOG_RETURN(RES_FAIL, "Layout::build() failed!");
+               }
+
+               return RES_OK;
+       }
+
+       Result AcceptRejectPresenter::createAcceptBtn()
+       {
+               m_accept = createBtn(impl::STYLE_BTN_ACCEPT,
+                               impl::PART_SWL_BTN_ACCEPT);
+               if (!m_accept) {
+                       LOG_RETURN(RES_FAIL, "createBtn() failed!");
+               }
+
+               return RES_OK;
+       }
+
+       Result AcceptRejectPresenter::createRejectBtn()
+       {
+               m_reject = createBtn(impl::STYLE_BTN_REJECT,
+                               impl::PART_SWL_BTN_REJECT);
+               if (!m_reject) {
+                       LOG_RETURN(RES_FAIL, "createBtn() failed!");
+               }
+
+               return RES_OK;
+       }
+
+       void AcceptRejectPresenter::onBtnPressed(Widget &widget, void *eventInfo)
+       {
+               if (widget == (*m_accept)) {
+                       m_widget->emit(impl::SIGNAL_REJECT_HIDE);
+               } else if (widget == (*m_reject)) {
+                       m_widget->emit(impl::SIGNAL_ACCEEPT_HIDE);
+               }
+       }
+
+       void AcceptRejectPresenter::onBtnUnpressed(Widget &widget, void *eventInfo)
+       {
+               if (widget == (*m_accept)) {
+                       m_widget->emit(impl::SIGNAL_REJECT_SHOW);
+               } else if (widget == (*m_reject)) {
+                       m_widget->emit(impl::SIGNAL_ACCEEPT_SHOW);
+               }
+       }
+
+       void AcceptRejectPresenter::onBtnClicked(Widget &widget, void *eventInfo)
+       {
+               if (widget == (*m_accept)) {
+                       processAccept();
+               } else if (widget == (*m_reject)) {
+                       processReject();
+               }
+       }
+
+       void AcceptRejectPresenter::processAccept()
+       {
+               if (m_callMask & CALL_FLAG_ACTIVE) {
+                       if (m_callMask & CALL_FLAG_HELD) {
+                               m_call->answer(CallAnswerType::RELEASE_ACTIVE_AND_ACCEPT);
+                       } else {
+                               showPopup();
+                       }
+               } else {
+                       m_call->answer(CallAnswerType::NORMAL);
+               }
+       }
+
+       void AcceptRejectPresenter::processReject() const
+       {
+               m_call->reject();
+       }
+
+       Eina_Bool AcceptRejectPresenter::onRotaryEvent(Eext_Rotary_Event_Info *info)
+       {
+               if (m_popup)
+                       LOG_RETURN_VALUE(RES_OK, EINA_TRUE, "Popup is shown. Ignore");
+
+               if (info->direction == EEXT_ROTARY_DIRECTION_CLOCKWISE) {
+                       m_reject->emit(impl::SIGNAL_BTN_UNPRESS);
+                       m_accept->emit(impl::SIGNAL_BTN_PRESS);
+               } else {
+                       m_reject->emit(impl::SIGNAL_BTN_PRESS);
+                       m_accept->emit(impl::SIGNAL_BTN_UNPRESS);
+               }
+               return EINA_TRUE;
+       }
+
+       StyledWidgetSRef AcceptRejectPresenter::createBtn(const ucl::ElmStyle &style,
+                       const ucl::EdjePart &part)
+       {
+               Evas_Object *const btnEo = elm_button_add(*m_widget);
+               if (!btnEo) {
+                       LOG_RETURN_VALUE(RES_FAIL, {}, "elm_button_add() failed!");
+               }
+               StyledWidgetSRef btn = makeShared<StyledWidget>(btnEo);
+               btn->setStyle(style);
+
+               btn->addEventHandler(impl::EVENT_PRESSED,
+                               WEAK_DELEGATE(AcceptRejectPresenter::onBtnPressed,
+                                               asWeak(*this)));
+
+               btn->addEventHandler(impl::EVENT_UNPRESSED,
+                               WEAK_DELEGATE(AcceptRejectPresenter::onBtnUnpressed,
+                                               asWeak(*this)));
+
+               btn->addEventHandler(BTN_CLICKED,
+                               WEAK_DELEGATE(AcceptRejectPresenter::onBtnClicked,
+                                               asWeak(*this)));
+
+               m_widget->setContent(*btn, part);
+               show(*btn);
+
+               return btn;
+       }
+
+       bool AcceptRejectPresenter::onAcceptPopupEvent(AcceptDialog &popup, AcceptDialogEvent event)
+       {
+               m_accept->emit(impl::SIGNAL_RESET);
+               m_widget->emit(impl::SIGNAL_RESET);
+
+               switch (event) {
+               case AcceptDialogEvent::HOLD_AND_ACCEPT:
+                       FAIL_RETURN_VALUE(
+                                       m_call->answer(CallAnswerType::HOLD_ACTIVE_AND_ACCEPT),
+                                       true, "incom->answer() failed!");
+                       return false;
+               case AcceptDialogEvent::END_AND_ACCEPT:
+                       FAIL_RETURN_VALUE(
+                                       m_call->answer(CallAnswerType::RELEASE_ACTIVE_AND_ACCEPT),
+                                       true, "incom->answer() failed!");
+                       return false;
+               default:
+                       return true;
+               }
+       }
+
+       void AcceptRejectPresenter::showPopup()
+       {
+               if (!m_popup) {
+                       m_popup = AcceptDialog::Builder().
+                                       setHandler(WEAK_DELEGATE(
+                                                       AcceptRejectPresenter::onAcceptPopupEvent,
+                                                       asWeak(*this))).
+                                       build(*m_widget);
+               } else {
+                       WLOG("Popup already shown!");
+               }
+       }
+
+}
index b90420446d211441ac3a4e8b5980ad3a260b5fe4..520e35b3f5403fb7d7de51cf4b8a848c2236258b 100644 (file)
  * limitations under the License.
  */
 
+#include "presenters/MainPage.h"
+
 #include "ucl/gui/Window.h"
 #include "ucl/gui/Layout.h"
 
-#include "presenters/MainPage.h"
-
 #include "model/ICall.h"
 #include "model/ICallManager.h"
 #include "model/IIncomingCall.h"
 #include "model/IHeldCall.h"
 #include "model/IEndCall.h"
 
+#include "presenters/AcceptRejectPresenter.h"
+
 #include "common.h"
 
+namespace callui { namespace { namespace impl {
+
+       using namespace ucl;
+
+       constexpr LayoutTheme LAYOUT_MAIN_WIDGET
+                       {"layout", "callui", "main"};
+
+       constexpr EdjePart PART_SWL_ACCEPT_REJECT {"swl.accept_reject"};
+}}}
+
 namespace callui {
 
        using namespace ucl;
@@ -98,11 +110,17 @@ namespace callui {
 
        Result MainPage::prepare()
        {
-               // TODO: Temporary. Need to implement with real layout
+               m_widget = Layout::Builder().
+                               setTheme(impl::LAYOUT_MAIN_WIDGET).
+                               setIsOwner(true).
+                               build(getNaviframe());
+               if (!m_widget) {
+                       LOG_RETURN(RES_FAIL, "Layout::build() failed!");
+               }
+
                return Page::prepare([this]() {
                        return getNaviframe().
-                                       push(*Layout::Builder().
-                                                       build(getNaviframe()));
+                                       push(*m_widget);
                });
        }
 
@@ -116,7 +134,12 @@ namespace callui {
 
        void MainPage::onCallEvent(CallEventType type)
        {
+               ILOG("CallEventType [%d]", static_cast<int>(type));
+
+               auto cm = m_call->getCallManager();
+               auto mask = cm->getAvailableCalls();
                auto win = getNaviframe().getWindow();
+
                if (!win) {
                        LOG_RETURN_VOID(RES_FAIL, "win is NULL");
                }
@@ -127,6 +150,18 @@ namespace callui {
                        show(*win);
                }
 
+               if (mask & CALL_FLAG_INCOMING) {
+                       if (!m_acceptReject) {
+                               FAIL_RETURN_VOID(createAcceptRejectPresenter(),
+                                               "createAcceptRejectPresenter() failed!");
+                       } else {
+                               m_acceptReject->update(cm->getAvailableCalls());
+                       }
+               } else {
+                       if (m_acceptReject)
+                               m_acceptReject.reset();
+               }
+
                if (type == CallEventType::END) {
                        if (m_call->getCallManager()->getAvailableCalls()
                                        == CALL_FLAG_END) {
@@ -135,6 +170,23 @@ namespace callui {
                }
        }
 
+       Result MainPage::createAcceptRejectPresenter()
+       {
+               auto callMng = m_call->getCallManager();
+               m_acceptReject = AcceptRejectPresenter::Builder().
+                               setIncomingCall(callMng->getIncomingCall()).
+                               setAvailableCallsFlag(callMng->getAvailableCalls()).
+                               build(*m_widget);
+               if (!m_acceptReject) {
+                       LOG_RETURN(RES_FAIL,
+                                       "AcceptRejectPresenter::Builder().build() failed!");
+               }
+               m_widget->setContent(m_acceptReject->getWidget().getEo(),
+                               impl::PART_SWL_ACCEPT_REJECT);
+
+               return RES_OK;
+       }
+
        void MainPage::onError(CallErr err)
        {
                if (!m_call->getCallManager()->getAvailableCalls()) {
diff --git a/src/resources.cpp b/src/resources.cpp
new file mode 100644 (file)
index 0000000..bb609ab
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * 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 "resources.h"
+
+namespace callui {
+
+       // TODO: Need replace with IDS
+
+       const ucl::TString STR_ANSWER_CALL {"Answer call"};
+       const ucl::TString STR_HOLD_AND_ACCEPT {"Hold and Accept"};
+       const ucl::TString STR_END_AND_ACCEPT {"End and Accept"};
+
+}
index 50d4f33388514ff387babe30ea89b9efc6b548da..bc05de34fd675dc1497ee81cc207734741df5e0e 100644 (file)
 
 #include "../common.h"
 
+namespace callui {
+
+       constexpr ucl::SmartEvent BTN_CLICKED {"clicked"};
+       constexpr ucl::SmartEvent POPUP_DELETE {"delete"};
+}
+
 #endif // __CALLUI_VIEW_COMMON_H__
index 9d1e0f790242b1e3929378dbef92e313747580f2..4b72176614948d6b089cbbff3b0f5ba647d307d8 100644 (file)
@@ -72,5 +72,41 @@ namespace callui {
                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)
+       {
+               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]);
+               }
+       }
+
+       Elm_Genlist_Item_Class createGenlistItemClass(const char *style,
+                       Elm_Gen_Item_Text_Get_Cb txtCb,
+                       Elm_Gen_Item_Content_Get_Cb contentCb,
+                       Elm_Gen_Item_State_Get_Cb stateCb,
+                       Elm_Gen_Item_Del_Cb delCb)
+       {
+               Elm_Genlist_Item_Class itc = { ELM_GEN_ITEM_CLASS_HEADER };
+               itc.item_style = style;
+               itc.func.text_get = txtCb;
+               itc.func.content_get = contentCb;
+               itc.func.state_get = stateCb;
+               itc.func.del = delCb;
+
+               return itc;
+       }
+
 }
 
index b340c34183c15cdf143c8b9c0b09acd7120df89a..89d33dd41bb6cf9f15aa3c9bed6182f24edb3f23 100644 (file)
@@ -39,6 +39,7 @@ namespace ucl {
        class IDisposable : public Polymorphic {
        public:
                virtual void dispose() = 0;
+               virtual bool isDisposed() const = 0;
        protected:
                virtual ~IDisposable() = default;
        };