2 * Copyright (c) 2021 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include "confirmation-popup-impl.h"
22 #include <dali/public-api/object/type-registry-helper.h>
23 #include <dali/public-api/object/type-registry.h>
27 #include <dali-toolkit/internal/controls/control/control-data-impl.h>
38 * This struct is used to define all details required about a dynamically created signal.
40 struct ControlDetailType
42 const char* signalName;
43 const char* controlName;
44 const char* connectSignalPropertyName;
48 /* A table of all control details. These details are kept in one place for maintainability.
49 * Name of the signal | Name of the control | Name of the property which lets the
50 * the app-developer | which will provide | app developer choose which signal
51 * can connect to. | the signal. | within the control to connect to. */
52 const ControlDetailType ControlDetails[] = {
53 {"controlSignalOk", "controlOk", "connectSignalOkSelected" },
54 {"controlSignalCancel", "controlCancel", "connectSignalCancelSelected"},
57 const unsigned int ControlDetailsCount = sizeof(ControlDetails) / sizeof(ControlDetails[0]);
59 // To give sensible default behaviour to save the connect signal properties being set.
60 const char* const DEFAULT_CONNECT_SIGNAL_NAME = "clicked";
64 return Toolkit::ConfirmationPopup::New();
67 DALI_TYPE_REGISTRATION_BEGIN(Toolkit::ConfirmationPopup, Toolkit::Popup, Create)
69 DALI_PROPERTY_REGISTRATION(Toolkit, ConfirmationPopup, ControlDetails[0].connectSignalPropertyName, STRING, CONNECT_SIGNAL_OK_SELECTED)
70 DALI_PROPERTY_REGISTRATION(Toolkit, ConfirmationPopup, ControlDetails[1].connectSignalPropertyName, STRING, CONNECT_SIGNAL_CANCEL_SELECTED)
72 // Note: We do not use the macros for signal registration as we do not want to redefine the signal name strings.
73 // We have predefined them for optimal signal name to control name lookup.
74 SignalConnectorType signalConnector1(typeRegistration, ControlDetails[0].signalName, &Toolkit::Internal::ConfirmationPopup::DoConnectSignal);
75 SignalConnectorType signalConnector2(typeRegistration, ControlDetails[1].signalName, &Toolkit::Internal::ConfirmationPopup::DoConnectSignal);
77 DALI_TYPE_REGISTRATION_END()
79 } // Unnamed namespace
81 Dali::Toolkit::ConfirmationPopup ConfirmationPopup::New()
83 // Create the implementation, temporarily owned on stack.
84 IntrusivePtr<ConfirmationPopup> internalConfirmationPopup = new ConfirmationPopup();
86 // Pass ownership to CustomActor
87 Dali::Toolkit::ConfirmationPopup confirmationPopup(*internalConfirmationPopup);
89 // Second-phase initialisation of the implementation.
90 // This can only be done after the CustomActor connection has been made...
91 internalConfirmationPopup->Initialize();
93 return confirmationPopup;
96 ConfirmationPopup::ConfirmationPopup()
97 : Toolkit::Internal::Popup()
99 mControlSignals.reserve(MAXIMUM_NUMBER_OF_CONTROLS);
100 mControlSignalNames[Toolkit::ConfirmationPopup::CONTROL_OK] = DEFAULT_CONNECT_SIGNAL_NAME;
101 mControlSignalNames[Toolkit::ConfirmationPopup::CONTROL_CANCEL] = DEFAULT_CONNECT_SIGNAL_NAME;
104 ConfirmationPopup::~ConfirmationPopup()
106 for(SignalContainerType::iterator i = mControlSignals.begin(); i != mControlSignals.end(); ++i)
110 mControlSignals.clear();
113 void ConfirmationPopup::SetProperty(BaseObject* object, Property::Index propertyIndex, const Property::Value& value)
115 Toolkit::ConfirmationPopup popup = Toolkit::ConfirmationPopup::DownCast(Dali::BaseHandle(object));
119 ConfirmationPopup& popupImpl(GetDerivedImplementation(popup));
121 switch(propertyIndex)
123 case Toolkit::ConfirmationPopup::Property::CONNECT_SIGNAL_OK_SELECTED:
125 popupImpl.SetControlSignalName(Toolkit::ConfirmationPopup::CONTROL_OK, value.Get<std::string>());
128 case Toolkit::ConfirmationPopup::Property::CONNECT_SIGNAL_CANCEL_SELECTED:
130 popupImpl.SetControlSignalName(Toolkit::ConfirmationPopup::CONTROL_CANCEL, value.Get<std::string>());
137 Property::Value ConfirmationPopup::GetProperty(BaseObject* object, Property::Index propertyIndex)
139 Property::Value value;
141 Toolkit::ConfirmationPopup popup = Toolkit::ConfirmationPopup::DownCast(Dali::BaseHandle(object));
145 ConfirmationPopup& popupImpl(GetDerivedImplementation(popup));
147 switch(propertyIndex)
149 case Toolkit::ConfirmationPopup::Property::CONNECT_SIGNAL_OK_SELECTED:
151 value = popupImpl.GetControlSignalName(Toolkit::ConfirmationPopup::CONTROL_OK);
154 case Toolkit::ConfirmationPopup::Property::CONNECT_SIGNAL_CANCEL_SELECTED:
156 value = popupImpl.GetControlSignalName(Toolkit::ConfirmationPopup::CONTROL_CANCEL);
165 void ConfirmationPopup::SetControlSignalName(const unsigned int controlNumber, const std::string& signalName)
167 if(controlNumber < ControlDetailsCount)
169 mControlSignalNames[controlNumber] = signalName;
173 std::string ConfirmationPopup::GetControlSignalName(unsigned int controlNumber) const
175 if(controlNumber < ControlDetailsCount)
177 return mControlSignalNames[controlNumber];
183 bool ConfirmationPopup::DoConnectSignal(BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor)
185 Dali::BaseHandle handle(object);
186 Toolkit::ConfirmationPopup popup = Toolkit::ConfirmationPopup::DownCast(handle);
188 // Look up the requested signal, attempting to create it dynamically if it doesn't exist.
189 SignalDelegate* signalDelegate = Dali::Toolkit::GetDerivedImplementation(popup).GetControlSignal(signalName);
192 // The signal delegate was created successfully, attempt to connect it to a callback if specified.
193 // If none is specified, the creation is still successful as the signal delegate can connect at a later time.
196 signalDelegate->Connect(tracker, functor);
201 // The signal could not be created.
205 SignalDelegate* ConfirmationPopup::GetControlSignal(const std::string& signalName)
207 // Check if the specified signal name already exists.
208 SignalContainerType::iterator end = mControlSignals.end();
209 for(SignalContainerType::iterator iter = mControlSignals.begin(); iter != end; ++iter)
211 // Find the first non-connected signal by matching signal name.
212 if((signalName == iter->first) && (!iter->second->IsConnected()))
214 // The requested signal (delegate) already exists, just return it.
219 // The signal doesn't exist, or it does but it's already connected to something else.
220 // To make a new connection to an existing signal, we need a new delegate,
221 // as delegates house a signal connection functor each.
222 // Check the signal name is valid and if so create the signal dynamically.
223 for(unsigned int i = 0; i < ControlDetailsCount; ++i)
225 if(0 == strcmp(signalName.c_str(), ControlDetails[i].signalName))
227 // The signal name is valid, check the respective actor to connect to exists.
228 Actor connectActor = Self().FindChildByName(ControlDetails[i].controlName);
231 // The actor exists, set up a signal delegate that will allow the application developer
232 // to connect the actor signal directly to their callback.
233 // Note: We don't use the GetControlSignalName() here for speedup, as we know the array bound is capped.
234 SignalDelegate* signalDelegate = new SignalDelegate(connectActor, mControlSignalNames[i]);
236 // Store the delegate with the signal name so we know what signals have been dynamically created so far.
237 mControlSignals.push_back(std::make_pair(signalName, signalDelegate));
239 // Return the delegate to allow connection to the newly created signal.
240 return signalDelegate;
243 // Signal name valid but could not connect to the control,
248 // Signal name was not found (invalid).
252 } // namespace Internal
254 } // namespace Toolkit