2 * Copyright 2012 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.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.tizenopensource.org/license
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.
20 #include <sys/types.h>
25 #include "mcfconfig.h"
27 #include "mcfcontext.h"
28 #include "mcfresource.h"
29 #include "mcfresourcecache.h"
33 CMCFUtils* CMCFUtils::sInstance; /* For singleton */
34 #define MCF_MAX_UNIQUE_ID 1000
36 CMCFUtils::CMCFUtils()
46 CMCFUtils::~CMCFUtils()
51 CMCFUtils* CMCFUtils::get_instance()
54 sInstance = new CMCFUtils();
56 return (CMCFUtils*)sInstance;
63 GetCMCFUtilsImpl()->get_screen_resolution(&mScnResolutionX, &mScnResolutionY);
64 mXScnRate = mScnResolutionX / (float)MCF_BASE_SCREEN_WIDTH;
65 mYScnRate = mScnResolutionY / (float)MCF_BASE_SCREEN_HEIGHT;
66 if(MCF_AUTO_DETECT_PORTRAIT_LANDSCAPE) {
67 /* If the width of screen is bigger than the height, switch portrait mode and landscape mode */
68 if(mScnResolutionX > mScnResolutionY) {
69 mXScnRate = mScnResolutionX / (float)MCF_BASE_SCREEN_HEIGHT;
70 mYScnRate = mScnResolutionY / (float)MCF_BASE_SCREEN_WIDTH;
74 mNinePatchInfoMap.clear();
78 * Returns a scale rate (see default screen resolution in mcfconfig.h file)
81 CMCFUtils::get_smallest_scale_rate()
83 /* Try to return smaller scale rate, to avoid UI crash */
84 return (mXScnRate < mYScnRate) ? mXScnRate : mYScnRate;
88 * Returns a scale rate X (see default screen resolution in mcfconfig.h file)
91 CMCFUtils::get_scale_rate_x()
93 /* Try to return smaller scale rate, to avoid UI crash */
98 * Returns a scale rate Y (see default screen resolution in mcfconfig.h file)
101 CMCFUtils::get_scale_rate_y()
103 /* Try to return smaller scale rate, to avoid UI crash */
108 * Recalculates x value according to the current screen resolution
111 CMCFUtils::scale_x(mcf16 *x)
119 * Recalculates y value according to the current screen resolution
122 CMCFUtils::scale_y(mcf16 *y)
130 * Returns a calculated x value according to the current screen resolution
133 CMCFUtils::get_scale_x(mcf16 x)
135 return static_cast<mcf16>(x*mXScnRate);
139 * Returns a calculated y value according to the current screen resolution
142 CMCFUtils::get_scale_y(mcf16 y)
144 return static_cast<mcf16>(y*mYScnRate);
148 * portable sleep function
151 CMCFUtils::sleep(mcfulong msc)
155 struct timeval toWait;
157 toWait.tv_sec = msc / 1000;
158 toWait.tv_usec = (msc % 1000) * 1000;
159 select(0, &dummy, NULL, NULL, &toWait);
164 * returns the composed path
167 CMCFUtils::get_composed_path(mcfchar* buf, int bufLength, const mcfchar* path)
172 if(mScnResolutionX == 0 || mScnResolutionY == 0) {
173 CMCFUtilsImpl *impl = GetCMCFUtilsImpl();
175 impl->get_screen_resolution(&mScnResolutionX, &mScnResolutionY);
179 const mcfchar *themename = NULL;
180 CMCFResourceCache *cache = CMCFResourceCache::get_instance();
182 themename = cache->get_cur_themename();
183 if (themename == NULL) {
184 themename = DEFAULT_THEME;
185 } else if (strlen(themename) == 0) {
186 themename = DEFAULT_THEME;
190 mcfboolean file_exists = FALSE;
191 snprintf(buf, bufLength, "%s/%dx%d/%s/%s", IMG_PATH_PREFIX, mScnResolutionX, mScnResolutionY, themename, path);
192 if(access(buf, R_OK) == 0) {
196 /* Check if the file exists in the current theme directory */
197 if (!file_exists && themename != DEFAULT_THEME) {
198 /* Use default theme name if not found */
199 snprintf(buf, bufLength, "%s/%dx%d/%s/%s", IMG_PATH_PREFIX, mScnResolutionX, mScnResolutionY, DEFAULT_THEME, path);
200 if(access(buf, R_OK) == 0) {
205 /* FIXME : Should look for what other resolutions are available */
206 /* If the file still doesn't exist, look for the file in different resolution */
208 /* Use default theme name if not found */
209 snprintf(buf, bufLength, "%s/%dx%d/%s/%s", IMG_PATH_PREFIX, MCF_BASE_SCREEN_WIDTH,
210 MCF_BASE_SCREEN_HEIGHT, DEFAULT_THEME, path);
211 if(access(buf, R_OK) == 0) {
216 /* Or maybe the path points the absolute path */
218 snprintf(buf, bufLength, "%s", path);
226 CMCFUtils::get_autopopup_window_variables(mcfchar * const autopopupKeys[MAX_SIZE_OF_AUTOPOPUP_STRING], mcfbyte *numKeys,
227 mcfbyte *numColumns, mcfbyte *numRows, mcfint *width, mcfint *height)
230 mcf_assert_return_false(autopopupKeys);
231 mcf_assert_return_false(numKeys && numColumns && numRows && width && height);
234 mcfboolean ret = FALSE;
237 if (autopopupKeys && numKeys && numColumns && numRows && width && height) {
239 for (loop = 0;loop < MAX_SIZE_OF_AUTOPOPUP_STRING;loop++) {
240 if (autopopupKeys[loop]) {
241 if (strlen(autopopupKeys[loop]) > 0) {
250 this->get_screen_resolution(&scrx, &scry);
252 CMCFContext *context = CMCFContext::get_instance();
254 *numColumns = (scrx - (2 * mcf_autopopup_configure.bgPadding)) /
255 (mcf_autopopup_configure.btnWidth + mcf_autopopup_configure.btnSpacing);
256 if (*numColumns > mcf_autopopup_configure.maxColumn && mcf_autopopup_configure.maxColumn > 0)
257 *numColumns = mcf_autopopup_configure.maxColumn;
258 *numRows = ((*numKeys - 1) / *numColumns) + 1;
259 if (*numColumns > *numKeys) *numColumns = *numKeys;
261 /* Try to spread evenly on each lines */
262 *numColumns = (*numKeys) / (*numRows);
263 if ((*numKeys) % *numRows != 0) (*numColumns)++;
266 (*numColumns * mcf_autopopup_configure.btnWidth) +
267 (2 * mcf_autopopup_configure.bgPadding) +
268 ((*numColumns - 1) * mcf_autopopup_configure.btnSpacing);
270 (*numRows * mcf_autopopup_configure.btnHeight) +
271 (2 * mcf_autopopup_configure.bgPadding) +
272 ((*numRows - 1) * mcf_autopopup_configure.btnSpacing);
274 *width += (2 * mcf_autopopup_configure.wndDecoSize);
275 *height += (2 * mcf_autopopup_configure.wndDecoSize);
282 * Returns a duplicated string pointer by given str
285 CMCFUtils::get_str_dup(const mcfchar* str)
292 length = strlen(str) + 1;
293 new_str = (mcfchar*)malloc(length);
294 memcpy(new_str, str, length);
295 new_str[length - 1] = '\0';
304 * Returns an unique ID
307 CMCFUtils::get_unique_id()
311 if (uniId < MCF_MAX_UNIQUE_ID) {
320 CMCFUtils::is_rect_overlap(McfRectangle rect1, McfRectangle rect2)
322 if (rect1.x < rect2.x + rect2.width && rect1.x + rect1.width > rect2.x &&
323 rect1.y < rect2.y + rect2.height && rect1.y + rect1.height > rect2.y) {
330 CMCFUtils::get_distance( mcfint x1, mcfint y1, mcfint x2, mcfint y2 )
334 return sqrt((dx * dx) + (dy * dy));
338 CMCFUtils::get_distance( McfPoint pt1, McfPoint pt2 )
340 return get_distance(pt1.x, pt1.y, pt2.x, pt2.y);
344 CMCFUtils::get_approximate_distance( mcfint x1, mcfint y1, mcfint x2, mcfint y2 )
346 mcfint dx = abs(x1 - x2);
347 mcfint dy = abs(y1 - y2);
352 CMCFUtils::get_approximate_distance( McfPoint pt1, McfPoint pt2 )
354 return get_approximate_distance(pt1.x, pt1.y, pt2.x, pt2.y);
357 const McfNinePatchInfo*
358 CMCFUtils::get_nine_patch_info(const mcfchar *imgPath)
362 if(!imgPath) return NULL;
364 /* FIXME : This is implemented in very inefficient way. Should optimize later. */
365 for (int loop = 0;loop < (sizeof(mcf_nine_patch_info) / sizeof(McfNinePatchInfo));loop++) {
366 mcfchar buf[_POSIX_PATH_MAX];
367 get_composed_path(buf, sizeof(buf), mcf_nine_patch_info[loop].imgPath);
368 if (strcmp(buf, imgPath) == 0) {
369 return &mcf_nine_patch_info[loop];
376 mcfint CMCFUtils::log(const mcfchar *fmt, ...)
382 va_start(argptr, fmt);
383 CMCFUtilsImpl *impl = GetCMCFUtilsImpl();
385 ret = impl->log(fmt, argptr);