From 0ddc708822485686aae20f2f3b9b570fa63708e2 Mon Sep 17 00:00:00 2001 From: chitta ranjan Date: Mon, 25 Mar 2013 21:28:53 +0900 Subject: [PATCH] Crop implementation Change-Id: I35e7850e97d81990aaf029e2f21a1332a0569cc4 Signed-off-by: chitta ranjan --- inc/IvImageCrop.h | 102 +++++ inc/IvImageSetterForm.h | 4 +- inc/IvImageViewerForm.h | 3 +- inc/IvTypes.h | 14 + res/screen-density-xhigh/EditBackground.png | Bin 0 -> 181 bytes .../T01-1_control_icon_CCW.png | Bin 0 -> 4850 bytes res/screen-density-xhigh/T01-1_control_icon_CW.png | Bin 0 -> 4904 bytes .../T01-1_control_icon_cancel.png | Bin 0 -> 4632 bytes .../T01-1_control_icon_save.png | Bin 0 -> 4454 bytes res/screen-density-xhigh/T01-1_crop_rectangle.png | Bin 0 -> 2813 bytes res/screen-density-xhigh/T01_1_controlbar_bg.png | Bin 0 -> 2832 bytes res/screen-size-normal/IDL_FORM_IMAGE_CROP.xml | 43 +++ src/IvFormFactory.cpp | 8 + src/IvImageCrop.cpp | 418 +++++++++++++++++++++ src/IvImageSetterForm.cpp | 15 +- src/IvImageViewerApp.cpp | 1 + src/IvImageViewerForm.cpp | 22 +- src/IvMainFrame.cpp | 1 + src/IvTypes.cpp | 13 + 19 files changed, 626 insertions(+), 18 deletions(-) create mode 100644 inc/IvImageCrop.h create mode 100644 res/screen-density-xhigh/EditBackground.png create mode 100644 res/screen-density-xhigh/T01-1_control_icon_CCW.png create mode 100644 res/screen-density-xhigh/T01-1_control_icon_CW.png create mode 100644 res/screen-density-xhigh/T01-1_control_icon_cancel.png create mode 100644 res/screen-density-xhigh/T01-1_control_icon_save.png create mode 100644 res/screen-density-xhigh/T01-1_crop_rectangle.png create mode 100644 res/screen-density-xhigh/T01_1_controlbar_bg.png create mode 100644 res/screen-size-normal/IDL_FORM_IMAGE_CROP.xml create mode 100644 src/IvImageCrop.cpp diff --git a/inc/IvImageCrop.h b/inc/IvImageCrop.h new file mode 100644 index 0000000..c247b0d --- /dev/null +++ b/inc/IvImageCrop.h @@ -0,0 +1,102 @@ +// +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// Licensed under the Flora License, Version 1.0 (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. +// + +/** + * @file IvImageCrop.h + * @brief This is the implementation file for Image Crop. + */ + +#ifndef _IV_IMAGE_CROP_H_ +#define _IV_IMAGE_CROP_H_ + +#include + +using namespace Tizen::Ui; + +enum TouchLocation +{ + INSIDE_CROPBOX = 0, + OUTSIDE_CROPBOX, + INSIDE_TOP_RECTANGLE, + INSIDE_BOTTOM_RECTANGLE, + INSIDE_LEFT_RECTANGLE, + INSIDE_RIGHT_RECTANGLE, + INSIDE_TOP_LEFT_RECTANGLE, + INSIDE_TOP_RIGHT_RECTANGLE, + INSIDE_BOTTOM_LEFT_RECTANGLE, + INSIDE_BOTTOM_RIGHT_RECTANGLE, +}; + +class ImageCropForm + : public Tizen::Ui::Controls::Form + , public::Tizen::Ui::IActionEventListener + , public Tizen::Ui::Scenes::ISceneEventListener + , public Tizen::Ui::ITouchEventListener +{ +public: + ImageCropForm(void); + + ~ImageCropForm(void); + + /*! @fn Initialize(void) + * @brief Called to construct the corresponding form of the file. + */ + bool Initialize(void); + + /*! @fn OnInitializing(void) + * @brief Called once the form has been constructed to initialize the controls within the form. + */ + virtual result OnInitializing(void); + + result OnDraw(void); + + virtual void OnActionPerformed(const Tizen::Ui::Control& source, int actionId); + + virtual void OnSceneActivatedN(const Tizen::Ui::Scenes::SceneId& previousSceneId, + const Tizen::Ui::Scenes::SceneId& currentSceneId, Tizen::Base::Collection::IList* pArgs); + virtual void OnSceneDeactivated(const Tizen::Ui::Scenes::SceneId& currentSceneId, + const Tizen::Ui::Scenes::SceneId& nextSceneId); + + // Callbacks from ITouchEventListener + virtual void OnTouchFocusIn(const Tizen::Ui::Control& source, const Tizen::Graphics::Point& currentPosition, const Tizen::Ui::TouchEventInfo& touchInfo){} + virtual void OnTouchFocusOut(const Tizen::Ui::Control& source, const Tizen::Graphics::Point& currentPosition, const Tizen::Ui::TouchEventInfo& touchInfo){} + virtual void OnTouchMoved(const Tizen::Ui::Control& source, const Tizen::Graphics::Point& currentPosition, const Tizen::Ui::TouchEventInfo& touchInfo); + virtual void OnTouchPressed(const Tizen::Ui::Control& source, const Tizen::Graphics::Point& currentPosition, const Tizen::Ui::TouchEventInfo& touchInfo); + virtual void OnTouchReleased(const Tizen::Ui::Control& source, const Tizen::Graphics::Point& currentPosition, const Tizen::Ui::TouchEventInfo& touchInfo); + + void CheckCurrentPosition(const Tizen::Graphics::Point currentPosition); + +private: + static const int IDA_BUTTON_SAVE = 105; + static const int IDA_BUTTON_CW_ROTATION = 102; + static const int IDA_BUTTON_CCW_ROATTION = 103; + static const int IDA_BUTTON_CANCEL = 104; + + Tizen::Graphics::Rectangle __cropBox; + Tizen::Base::String __destFilePath; + Tizen::Graphics::Rectangle __imageBox; + Tizen::Media::ImageBuffer __imageBuffer; + int __imageHeight; + int __imageWidth; + Tizen::Graphics::Canvas* __pCanvas; + Tizen::Graphics::Bitmap* __pCurrentBitmap; + Tizen::Graphics::Bitmap* __pRectangleBitmap; + TouchLocation __pointLocation; + Tizen::Graphics::Point __touchStart; + Tizen::Media::ImageFormat __imageFormat; +}; + +#endif /* _IV_IMAGE_CROP_H_ */ diff --git a/inc/IvImageSetterForm.h b/inc/IvImageSetterForm.h index 7b1c7dd..cc3a9fe 100644 --- a/inc/IvImageSetterForm.h +++ b/inc/IvImageSetterForm.h @@ -51,7 +51,7 @@ public: virtual void OnActionPerformed(const Tizen::Ui::Control& source, int actionId); - virtual void OnOrientationChanged(const Tizen::Ui::Control &source, + virtual void OnOrientationChanged(const Tizen::Ui::Control& source, Tizen::Ui::OrientationStatus orientationStatus); virtual void OnFormBackRequested(Tizen::Ui::Controls::Form& source); @@ -81,7 +81,7 @@ private: int __statusValue; int __currentImageIndex; long long __contentId; - Tizen::Graphics::Bitmap* __currentBitmap; + Tizen::Graphics::Bitmap* __pCurrentBitmap; ImageViewerPresentationModel* __pPresentationModel; }; diff --git a/inc/IvImageViewerForm.h b/inc/IvImageViewerForm.h index fc6f92d..059d97f 100644 --- a/inc/IvImageViewerForm.h +++ b/inc/IvImageViewerForm.h @@ -139,7 +139,7 @@ private: result ShowPanelDetail(bool showStatus); result ChangeFooterItem(bool isChanged, Tizen::Ui::Controls::Footer* pFooter, int position); long long GetFileSize(Tizen::Base::String filePath); - void GetHeaderString(int index, Tizen::Base::String &fileName, Tizen::Base::String &page); + void GetHeaderString(int index, Tizen::Base::String& fileName, Tizen::Base::String& page); void DownloadFile(void); void CallVideoPlayer(void); result DeleteImageFile(void); @@ -164,7 +164,6 @@ private: Tizen::Ui::Controls::FooterItem* __pDetailFooterItem; Tizen::Ui::Controls::Gallery* __pGallery; Tizen::Base::Runtime::Timer* __pTimer; - Tizen::Graphics::Bitmap* __pDecodeBitmap; Tizen::Ui::Controls::ContextMenu* __pContextMenuMore; Tizen::Ui::Controls::ContextMenu* __pContextMenuCopy; Tizen::Ui::Controls::ContextMenu* __pContextMenuSetAs; diff --git a/inc/IvTypes.h b/inc/IvTypes.h index 4efeaeb..a40e602 100644 --- a/inc/IvTypes.h +++ b/inc/IvTypes.h @@ -58,6 +58,7 @@ enum ActionID , ACTION_ID_FOOTER_BUTTON_SLIDE = 407 , ACTION_ID_FOOTER_BUTTON_SHARE = 408 , ACTION_ID_FOOTER_BUTTON_SAVE = 409 + , ACTION_ID_FOOTER_BUTTON_CROP = 412 , ACTION_ID_FOOTER_MORE = 501 , ACTION_ID_PANEL_HEADER_DETAILS_RENAME = 601 }; @@ -72,13 +73,16 @@ enum SlideShowTransitionEffect extern const wchar_t* IDL_FORM_IMAGE_VIEWER; extern const wchar_t* IDL_FORM_IMAGE_SETTER; extern const wchar_t* IDL_FORM_NAME_EDITOR; +extern const wchar_t* IDL_FORM_IMAGE_CROP; extern const wchar_t* FORM_IMAGE_VIEWER; extern const wchar_t* FORM_IMAGE_SETTER; +extern const wchar_t* FORM_IMAGE_CROP; extern const wchar_t* FORM_IMAGE_NAME_EDITOR; extern const wchar_t* IDSCN_IMAGE_VIEWER; extern const wchar_t* IDSCN_IMAGE_SETTER; +extern const wchar_t* IDSCN_IMAGE_CROP; extern const wchar_t* IDSCN_IMAGE_NAME_EDITOR; extern const wchar_t* APPCONTROL_PROVIDER_ID_MESSAGES; @@ -159,6 +163,12 @@ extern const wchar_t* IDB_IMAGE_VIEWERFORM_MORE_NORMAL; extern const wchar_t* IDB_IMAGE_VIEWERFORM_MORE_PRESSED; extern const wchar_t* IDB_IMAGE_VIEWERFORM_FOOTER_ICON_SHARE_NORMAL; extern const wchar_t* IDB_IMAGE_VIEWERFORM_FOOTER_ICON_DELETE_NORMAL; +extern const wchar_t* IDB_IMAGE_CROP_FORM_SAVE_ICON; +extern const wchar_t* IDB_IMAGE_CROP_FORM_CANCEL_ICON; +extern const wchar_t* IDB_IMAGE_CROP_FORM_CW_ROTATION_ICON; +extern const wchar_t* IDB_IMAGE_CROP_FORM_CCW_ROTATION_ICON; +extern const wchar_t* IDB_IMAGE_CROP_FORM_ITEM_DIVIDER_ICON; +extern const wchar_t* IDB_IMAGE_CROP_RECTANGLE; extern const wchar_t* IDB_IMAGE_SETTERFORM_BUTTON_SET; extern const wchar_t* IDB_IMAGE_SETTERFORM_BUTTON_SET_PRESS; @@ -179,4 +189,8 @@ extern const wchar_t* ENTRY_NAME_IMAGE_VIEWER_SHUFFLE_VALUE; extern const wchar_t* DEVICE_STORAGE_CARD_MOUNTED; extern const wchar_t* DEVICE_STORAGE_CARD_UNMOUNTED; +extern const int FOOTER_PANEL_HEIGHT; +extern const int INDICATOR_BAR_HEIGHT; +extern const int CROP_RECTANGLE_HEIGHT; + #endif /* _IV_TYPES_H_ */ diff --git a/res/screen-density-xhigh/EditBackground.png b/res/screen-density-xhigh/EditBackground.png new file mode 100644 index 0000000000000000000000000000000000000000..a6bcaa56c21aa5653ab19c2ed3aac9a8826c3cce GIT binary patch literal 181 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V8<6ZZI=>f4F%}28J29*~C-V}>VM%xNb!1@J z*w6hZkrl{SNcITwWnidMV_;}#VPNhJyShX&#pfYfQtA$T^vI+f|C;@SeuPm7#L?U VFoqbln*n7QJYD@<);T3K0RU=YE9(FN literal 0 HcmV?d00001 diff --git a/res/screen-density-xhigh/T01-1_control_icon_CCW.png b/res/screen-density-xhigh/T01-1_control_icon_CCW.png new file mode 100644 index 0000000000000000000000000000000000000000..a39964e504c5f48be4808f85f9bc4a0ab9c2eec6 GIT binary patch literal 4850 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 Y0N6+Dn12UqlK=n!07*qoM6N<$f(PRlCIA2c literal 0 HcmV?d00001 diff --git a/res/screen-density-xhigh/T01-1_control_icon_CW.png b/res/screen-density-xhigh/T01-1_control_icon_CW.png new file mode 100644 index 0000000000000000000000000000000000000000..c2a192c86a7154ad44e83c617c3164b54524284b GIT binary patch literal 4904 zcmV+@6W8pCP)KLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z000P6Nkle`jQslL#)Ok+~q zBy*9Jti0HZ4HM@pW>9A}8Dr@Ztv0)zBi$whHEJc(jZ%@?vJnj-g2yJk1@cU9q7a%V8-Me>hr4Yh8=c*b94SA}uvGI`8>HIWY?{GLAj=a3Qmw~SX3shZJAbnt9 z;MY=0>2|yS2BbdDgXYVW5rB68{{3=~$I~k#w5?mW{ubD(fF!HBl7Os^j*dFxzSh>( z9|6fTY0Z29Vrgh-SUfQ?aZN^HM~)o%JMbE?5m*dps;&jV%9fUvw*qv=QB_s7!nkL? z0TF<;qoboZ8n2L2%9fUvUZ7fe$1_S)g{mtBSatE@#diXq>FVk_uCzwXHy~P5Q_~us z&o??;l#T3ju3DT`9oo=H}*e!Ou1{G&~O^hJx~> zfLMTZUDrPf)!F|3{_*YGw_gR$0B1ToJ6*x|l$4ab4g3Ts2A)<+wg?8&)YSCn;AdSf z*FS>+KFMWQ07V`F10 za2MzW9sph$W{+$(+lKb`_8$X@vz-cr;~^UGHC@*o!6Vn%+38xkbm{Mbp98M|F9JJq zb8`>6-R?&Lx^V#52CP(iUqa*lpc@gVMRs7%3y(=>nS6El)AdQFNEe}V`G!+ z*RMYXR4NdwfLvf5@JeA};qhI&b~ONpfSo|zbZ#FG5T!%sfb^iLHm5)=z*pPb+kY3_ zIJ@2cA@Dlzf{G{7RV=X>_%^T`_$ly1;9H?|BT^tzN_qM6fnN=rl$9SF5n(82#l*x{vq%w@JOu;ZeR!)jYK!5v%K|9|m+OrC)XS5pW;q20E39x`0U;ho2fGCnslicXuBEl4e6-En#>_lGp1E zm1GU6j*m+zeF5(119asPBWgv73k<`uva()1dGh2MBQcyyAQq+Sp+@4N>bNJw9F@vr z{KnjmXQMSuODioceZ$y3nCm@N(cRtM7yM;yZS86`ha>8&O7pE_V`JNWK3~J&;NS`& zghj1rVVlin+i?B*^_PtZcCLU(z~^*2hl2~&u3fv**bh=B*#_cO%jj5ZYwIV$g&Q|+d{ymZSROY`u3o)bv~1b3 zW5MO)cS91N zTGFktjIPaQ+i>U3ou9=+V8anr9T+`$@Zh!K;o*lN?nze-2?^uIjT=RUg@u2yTCM4` znWQdXzWlX{ii+%51vVTYlPb6xx^Usb|9FYh>2#GesoUX2}fvT#iw}Ru4CjrB-jEs!$UAlDX#VuR5G^l}; zvjM~(kf3#!m6g2%Jf*y*N5S$2dfnl}hcnl$TX$wIVHj3aRCGiof39efzi?d3NZ5u| zcH0iLs=uAUXKFMMLRgL+JC?a`-@c~A#KbI~fT`rK+SnqP4Isv9Gp4fJ+raz4E#P0u zQ#?WlOMQL)lD&KPHig=1oJ-5i&D|eu@)s@;LtICJe&F9gpUQT1K-AaQFWI?sXLC|g z(kkYGMVtIZan1dzOK+qR?g35H<>1qFvID=Q<4 zO)Rm(7#SIPGb1BoJM+*qO-rk+to%hJ$)6<#7)dUd>&=A=7w%vlTTV{SZoA$7op6&s zOAIjnV6)kNz?Z;EN=lBRep(T4AOc7n7#R4~mjwnuYHI2?&YwSD5{|$|3d9PeB_<|r zidSQ=T)Fa*iiRa1`}+EZW&?`D;jk$!i8*u+29j>K+Z#7++LWQ|dWzTU)tEXoiexKM zS}Ydd>C>mL)zs8{z|=;y5Ac+gm0g&am{?IV|_5)vlw-o1N!&z?OW zD-W^E6w=Rl`W0d$Yyq$oSi{uOWw!b*(nkALkk_Lk-cQu$MZmMbH<>yXO(V9I(64fu zd%y=qsu6f>603*!RX{eR!uHWndm&+_0uNNw+o#fkN%gl+wQGbJwibg@4yVewCR87Y zmxowYIBWyHqUNME%8{E;jdiKW*Q=JsRHhEa)1pn#LZloIRXuLNGt)Uyq(FpnVNEqY z+O0q1=bRn|!Vp!V-f6tw5(glDRfnNdGoG6X^FO=eo6DF$Oduu@6NqUh5EFKLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z000L=Nkl6+#|ZKKbA_R)|qba6lYCl z7)H%kwYUJ^_3PJhV!y9G;68FRst$^Oub>(=_cnfKTGG z^f~PSQGiu5Gc(^bs#vjD%*0}`UNgW(!WbDD>0DS?c)yz8`T6-j0Iii!oCcx*tCGp& zNn;5s7K@o^G`g!%PykOj91iHZeq|}YnM~$2psgH=lR#>MVOpV3xM3HH`1HnNvEIeS zMYR^cnx?&84#g=T3eYk!F>%nS!wQAMjYJ}G*a{SLor=X`y~ScNQ;%O&RljeRk5fQA zz(?Zo_-_phrmE@*przITO&HN=bXTEJxKXdabUOVm@KL~5>u0QY4)FpVnx=JFX_Z}F zUB6aU^%&4{x3(;Q_eP`9&u-toea!3iuBq3brfCJ>Udc>H+HNbb>EOYG1G!vIH!NB* znLG)sx>Kf@nUP2&4qM3#(~cfJ`aNJPu-d7TX$2ktzTDs6e=eKN=B)-hH#he}wfZ*K zDOFWZSiN^Po6Yz2^^E|Bfo`DPDIh*zJ+KRSwx_4(_wjfNJTkGG+i9n3C_ef##k z349ya19Snaoa{0kz-FKics>vaygE5Kso8|mCJT1W?R*IsZvjEzOTedqHGs#-Im9Om z)fQks@LV7eIA;e+I-R}%+&ecn_d)|ZH! zYOAI5JPw=$ULG48OEeM2IpABs7lDV$<_@LVyWL7C_XE3u0pORBNMyPRFv7qoDcem_ z#>=+-zwJn%v;&`zmi#pEqEk>tM@N&uZ-8f|Tpy5sipTB%+7KXRE%_c`1JDb61Ng=8 z@Nle=FviBl62MDRo{!f8V_ATdL1_a5z~_Lk1H-{!@a;yxh(sdOz>B~!;PXid2`|P>C@lg3V{yzc4uCQ}Ao1UJ2 z#*`0MJdj3d8TDu?D;7v2v<$17%8CQh2ra{|rm|vy)O$4H5R@gmPBZs13eajt%b1^^ zUp#c^&^ySfl;Pq{8%*59{^|UXezp{Ul|!0>8ym(jI-S~P19a)fR^!`s9d{6;CTjk$&RL? z>-v>&I2zS|d9x)SR6=o5b#INwho?yir?rAwC*eSLjz3XH!13Hk8148tf% zS{sU@ECAQd(g#XILqkQt7#tkjS&z@z+1ZR}tn)y@sk7Y&w{G2fL{-%fEeJbLRcaYa zl%}bv>;Rqs21B9HcpYQ?jV)WY9B;3UTcMB{S3`T*Ui=@~qYFgXf z>bgu*`8cp$&S_8A0%dAyD&5u9^(){jvS2%UwtJr_VaI@%mzo)Z!Qk7#&w!&MDb@s| za(@JT4Cn#A2K;2to;{;?I%t;;_6l%91aCjk;$)Y(2iORFL7Y~d8A74ZI4~&bzC+T# z4Qo#jl|%U|@WZ`(_x`C8O4)34N;=pl>+Ld1J*tyD4_ zqQI1Ns43}Sw}4`;Zmj?@p|k<(BwIGi&$U1i_$M$eZ8aq@7Nu)gepXjXwnMV*LAm^r zL0Mo1h>LF%MyYI9-te|-TB&SiC;&MLV2uDt1AhbNq~+O#VYc9c+^+=W0ZmHDCoy~o z%u3t74WlmV7Bl2O9?_H%>X584VP(y9Z2*i)pI-5`S}v~u$^tj#_fi$z#&IBKfFAQP zZh5Wf0Ejz*G5warXQ`TBM}WBBhH!zn<^pknxIkPWE)W-p3#4iGuK@sNp5(J3(4{s2 O0000KLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z000J&Nklst8(% zL)9L8LPFwDaY>v5tq@gmSRtf}6Oo|p9x4^8g0_uBmQCp)EMy&#WE?lakl4hI=U)$b z)4GVzc;YEeJ3lFM#`8RW@AH1Y?|Z-Zo+aD1@$Fw0@Dcbxd>}p$ABYdc2jT08uVoy0pWtF*8kb;o-xF9|^CQ+yYT5^im0^ zJ8TdP)MMy?ghDPn|l| zV%xR^FgiM#xqbU~#_1Sf%bh!SCLJIEvMe_qI&|oFZlSpG5LwrCb+rPjs+NGqzy$DI zRLGSF+`W7ESMhkf*Ll-4&77hrhXv$1;Omh{r1kX=%d*_q)z$TQB_qNUvDUo2VOe$h(sbUR(nVyk@!CF1@OvCAaC#5K)?c)fP!t? z%dQktl2jm6EEemc(dg^9qaqZGz*1dZ-KyU)KR+J10b6vy8!eyDHvkQQywRub0YEiP^Gyw@TWh_A)&(nRXHDlag+ifFeqAgUiE(PoF+bUA%bl_rTYH9PpKR)t$LYPfySOng$Y$Mq|Un!vpDb`j^>kc3PI@iUn5F zG&z+@g&#kD9G{(?RSJbdF>m@p!yx&z?OWw6wImFGAvYYisMNng#+8kH-(jDzd)GUy(v9Ya!sz6Dm+YQw-XV2TyG+8=hy7K$tZs8q>9%^S=VNu5!i?TQZA z5I}6vi_foJyVkk5xVTBzb=Th)2m}HR4GrOmi3zE{zdz^E=;b*Ob9#FE?Dp;3e_l;d z?eFjZhF5DMUQXR5Kza7;+20MrsG9KQa=9;s7RejULnNTSySsZ7I9DdBZchq0qB;eH zL^y6JAWkDp5%0R_RkuJ)AA-(QLrSMlpEk~&J9nV5v2mwi7_zf1>1H@LO*4Dz z)~(rOGU-)H;Jv603=I5e>(;G5tJXu0969pCWHPzKD-ZEnRD zGqvO)0YL5T?fo41DX>)}WNyu1W%E2GM76jffW%_4SebBILQIRS?DyL15LF#0h|$GK z4W#z=_FXj%BpQvzG))^wrBc5Lhr_z2X`ysF9m(hOs;=v}jeTdPx_R^F9XogKY^txX zH!aKhsI9H-C3l}c@vC=t-D8lDWvOqgJoH&&?j3})ukIZZhQuO4*U&Bul1}-r9dPxQoIMW0lR@X zD@P8bvUJ}`(@ngYFGxj zhLz(~rdJ{3^o}eNwM}A@w4NNr3n0!AT@e3UYi*|+AmwfwD0AOhF}o}o{O7eNK>i=h s-`n+p_&|IhJ`f*>55x!ZuIwKJ02sC5qSWY|Q~&?~07*qoM6N<$g0k0S7ytkO literal 0 HcmV?d00001 diff --git a/res/screen-density-xhigh/T01-1_crop_rectangle.png b/res/screen-density-xhigh/T01-1_crop_rectangle.png new file mode 100644 index 0000000000000000000000000000000000000000..6e89c378e0f8e79eaa27b18fd92b3af58da7fd18 GIT binary patch literal 2813 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 i0Zf?#qK0;b3}65&#&^MKN6H`o0000 + + + + 720 +
+ + + + + + + + + + + + + + +
diff --git a/src/IvFormFactory.cpp b/src/IvFormFactory.cpp index fab0b52..e70474f 100644 --- a/src/IvFormFactory.cpp +++ b/src/IvFormFactory.cpp @@ -23,6 +23,7 @@ #include "IvImageNameEditorForm.h" #include "IvImageViewerForm.h" #include "IvImageSetterForm.h" +#include "IvImageCrop.h" using namespace Tizen::Base; using namespace Tizen::Ui::Controls; @@ -60,6 +61,13 @@ FormFactory::CreateFormN(const String& formId, const SceneId& sceneId) SceneManager::GetInstance()->AddSceneEventListener(sceneId, *pForm); pNewForm = pForm; } + else if (formId == FORM_IMAGE_CROP) + { + ImageCropForm* pForm = new (std::nothrow) ImageCropForm(); + pForm->Initialize(); + SceneManager::GetInstance()->AddSceneEventListener(sceneId, *pForm); + pNewForm = pForm; + } else if (formId == FORM_IMAGE_NAME_EDITOR) { ImageNameEditorForm* pForm = new (std::nothrow) ImageNameEditorForm(); diff --git a/src/IvImageCrop.cpp b/src/IvImageCrop.cpp new file mode 100644 index 0000000..6c06fc5 --- /dev/null +++ b/src/IvImageCrop.cpp @@ -0,0 +1,418 @@ +// +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// Licensed under the Flora License, Version 1.0 (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. +// + +/** + * @file IvImageCrop.cpp + * @brief This is the implementation file for Image Crop. + */ + +#include +#include +#include "IvImageCrop.h" +#include "IvImageViewerPresentationModel.h" +#include "IvTypes.h" + +using namespace Tizen::App; +using namespace Tizen::Base; +using namespace Tizen::Base::Collection; +using namespace Tizen::Graphics; +using namespace Tizen::Media; +using namespace Tizen::Ui::Controls; +using namespace Tizen::Ui::Scenes; + +static const unsigned int CROP_BOX_RECTANGLE_COLOR = Color32<199, 110, 6>::Value; +static const int CROP_BOX_LINE_WIDTH = 5; + +ImageCropForm::ImageCropForm(void) + : __imageHeight(0) + , __imageWidth(0) + , __pCanvas(null) + , __pCurrentBitmap(null) + , __pRectangleBitmap(null) +{ + __pointLocation = OUTSIDE_CROPBOX; +} + +ImageCropForm::~ImageCropForm(void) +{ + if (__pCurrentBitmap != null) + { + delete __pCurrentBitmap; + } + + if (__pRectangleBitmap != null) + { + delete __pRectangleBitmap; + } + + if (__pCanvas != null) + { + delete __pCanvas; + __pCanvas = null; + } +} + +bool +ImageCropForm::Initialize(void) +{ + Form::Construct(IDL_FORM_IMAGE_CROP); + Form::SetFormStyle(FORM_STYLE_NORMAL | FORM_STYLE_INDICATOR); + return true; +} + +result +ImageCropForm::OnInitializing(void) +{ + result r = E_SUCCESS; + + AppResource* pAppResource = null; + Bitmap* pSaveButtonBitmap = null; + Bitmap* pCancelButtonBitmap = null; + Bitmap* pCWRotationButtonBitmap = null; + Bitmap* pCCWRotationButtonBitmap = null; + Panel* pPanel = null; + Button* pSaveButton = null; + Button* pCancelButton = null; + pAppResource = UiApp::App::GetInstance()->GetAppResource(); + if (pAppResource != null) + { + pSaveButtonBitmap = pAppResource->GetBitmapN(IDB_IMAGE_CROP_FORM_SAVE_ICON); + pCancelButtonBitmap = pAppResource->GetBitmapN(IDB_IMAGE_CROP_FORM_CANCEL_ICON); + pCWRotationButtonBitmap = pAppResource->GetBitmapN(IDB_IMAGE_CROP_FORM_CW_ROTATION_ICON); + pCCWRotationButtonBitmap = pAppResource->GetBitmapN(IDB_IMAGE_CROP_FORM_CCW_ROTATION_ICON); + __pRectangleBitmap = pAppResource->GetBitmapN(IDB_IMAGE_CROP_RECTANGLE); + } + + pPanel = static_cast(GetControl(L"IDC_FOOTER_PANEL")); + if (pPanel != null) + { + pSaveButton = static_cast(pPanel->GetControl(L"IDC_SAVE_BUTTON")); + if (pSaveButton != null) + { + Point startPoint((pSaveButton->GetWidth() - pSaveButtonBitmap->GetWidth()) / 2,(pSaveButton->GetHeight() - pSaveButtonBitmap->GetHeight()) / 2 ); + pSaveButton->SetNormalBitmap(startPoint, *pSaveButtonBitmap); + pSaveButton->AddActionEventListener(*this); + pSaveButton->SetActionId(IDA_BUTTON_SAVE); + } + + pCancelButton = static_cast(pPanel->GetControl(L"IDC_CANCEL_BUTTON")); + if (pCancelButton != null) + { + Point startPoint((pCancelButton->GetWidth() - pCancelButtonBitmap->GetWidth()) / 2,(pCancelButton->GetHeight() - pCancelButtonBitmap->GetHeight()) / 2 ); + pCancelButton->SetNormalBitmap(startPoint, *pCancelButtonBitmap); + pCancelButton->AddActionEventListener(*this); + pCancelButton->SetActionId(IDA_BUTTON_CANCEL); + } + Label* pLabel = static_cast(pPanel->GetControl(L"IDC_PANEL_LABEL")); + if (pLabel != null) + { + SetControlAlwaysOnTop(*pPanel, true); + } + SetControlAlwaysAtBottom(*pLabel, true); + } + AddTouchEventListener(*this); + + delete pSaveButtonBitmap; + delete pCancelButtonBitmap; + delete pCWRotationButtonBitmap; + delete pCCWRotationButtonBitmap; + return r; +} + +void +ImageCropForm::OnSceneActivatedN(const SceneId& previousSceneId, const SceneId& currentSceneId, IList* pArgs) +{ + AppLogDebug("ENTER"); + String* pFilePath = null; + if (pArgs != null) + { + pFilePath = static_cast(pArgs->GetAt(0)); + delete pArgs; + } + __destFilePath.Append(*pFilePath); + __destFilePath.Reverse(); + int index = 0; + String delimiter = L"."; + __destFilePath.IndexOf(delimiter, 0, index); + __destFilePath.Reverse(); + String stringToInsert = L"_1"; + __destFilePath.Insert(stringToInsert, __destFilePath.GetLength() - index - 1); + __imageBuffer.GetImageInfo(pFilePath->GetPointer(), __imageFormat, __imageWidth, __imageHeight); + __imageBuffer.Construct(pFilePath->GetPointer()); + __pCurrentBitmap = __imageBuffer.GetBitmapN(BITMAP_PIXEL_FORMAT_RGB565, BUFFER_SCALING_AUTO); + + if (__imageWidth > GetClientAreaBounds().width && __imageHeight > GetClientAreaBounds().height) + { + if (__imageHeight > __imageWidth) + { + __imageBox.height = GetClientAreaBounds().height - FOOTER_PANEL_HEIGHT; + __imageBox.width = (__imageWidth * GetClientAreaBounds().height) / __imageHeight; + __imageBox.x = (GetClientAreaBounds().width - __imageBox.width) / 2; + __imageBox.y = INDICATOR_BAR_HEIGHT; + } + else + { + __imageBox.width = GetClientAreaBounds().width; + __imageBox.height = (GetClientAreaBounds().width * __imageHeight) / __imageWidth; + __imageBox.x = 0; + __imageBox.y = (GetClientAreaBounds().height - __imageBox.height) / 2; + } + } + else if (__imageWidth > GetClientAreaBounds().width) + { + __imageBox.width = GetClientAreaBounds().width; + __imageBox.height = (__imageHeight * GetClientAreaBounds().width) / __imageWidth; + __imageBox.x = 0; + __imageBox.y = (GetClientAreaBounds().height - __imageBox.height) / 2; + + } + else if (__imageHeight > GetClientAreaBounds().height) + { + __imageBox.height = GetClientAreaBounds().height - FOOTER_PANEL_HEIGHT; + __imageBox.width = (__imageWidth * GetClientAreaBounds().height) / __imageHeight; + __imageBox.x = (GetClientAreaBounds().width - __imageBox.width) / 2; + __imageBox.y = INDICATOR_BAR_HEIGHT; + } + else + { + __imageBox.height = __imageHeight; + __imageBox.width = __imageWidth; + __imageBox.x = (GetClientAreaBounds().width - __imageBox.width) / 2; + __imageBox.y = (GetClientAreaBounds().height - __imageBox.height) / 2 ; + } + if (__imageHeight >= __imageWidth) + { + __cropBox.height = __imageBox.height / 2; + __cropBox.width = __imageBox.width / 2; + __cropBox.y = __imageBox.y + (__imageBox.height / 4); + __cropBox.x = __imageBox.x + (__imageBox.width / 4); + } + else + { + __cropBox.height = (2 * __imageBox.height) / 3; + __cropBox.width = (2 * __imageBox.width) / 3; + __cropBox.y = __imageBox.y + (__imageBox.height - __cropBox.height) / 2; + __cropBox.x = __imageBox.x + (__imageBox.width - __cropBox.width) / 2; + } + + __pCanvas = GetCanvasN(); + __pCanvas->SetForegroundColor(CROP_BOX_RECTANGLE_COLOR); + AppLogDebug("EXIT(%s)", GetErrorMessage(GetLastResult())); +} + +void +ImageCropForm::OnSceneDeactivated(const SceneId& currentSceneId, const SceneId& nextSceneId) +{ + AppLogDebug("ENTER"); + AppLogDebug("EXIT(%s)", GetErrorMessage(GetLastResult())); +} + +result +ImageCropForm::OnDraw(void) +{ + result r = E_SUCCESS; + AppLogDebug("ENTER"); + if (__pCanvas != null) + { + __pCanvas->SetLineWidth(CROP_BOX_LINE_WIDTH); + __pCanvas->DrawBitmap(Rectangle(__imageBox.x, __imageBox.y, __imageBox.width, __imageBox.height), *__pCurrentBitmap); + __pCanvas->DrawRectangle(Rectangle(__cropBox.x, __cropBox.y, __cropBox.width, __cropBox.height)); + __pCanvas->DrawBitmap(Rectangle((__cropBox.x + __cropBox.width / 2) - (CROP_RECTANGLE_HEIGHT / 2), __cropBox.y - (CROP_RECTANGLE_HEIGHT / 2), CROP_RECTANGLE_HEIGHT, CROP_RECTANGLE_HEIGHT), *__pRectangleBitmap); // Top Rectangle + __pCanvas->DrawBitmap(Rectangle((__cropBox.x + __cropBox.width / 2) - (CROP_RECTANGLE_HEIGHT / 2), (__cropBox.y + __cropBox.height - (CROP_RECTANGLE_HEIGHT / 2)), CROP_RECTANGLE_HEIGHT, CROP_RECTANGLE_HEIGHT), *__pRectangleBitmap); // Bottom Rectangle + __pCanvas->DrawBitmap(Rectangle(__cropBox.x - (CROP_RECTANGLE_HEIGHT / 2), (__cropBox.y + __cropBox.height / 2) - (CROP_RECTANGLE_HEIGHT / 2), CROP_RECTANGLE_HEIGHT, CROP_RECTANGLE_HEIGHT), *__pRectangleBitmap); //Left Rectangle + __pCanvas->DrawBitmap(Rectangle(__cropBox.x + __cropBox.width - (CROP_RECTANGLE_HEIGHT / 2), (__cropBox.y + __cropBox.height / 2) - (CROP_RECTANGLE_HEIGHT / 2), CROP_RECTANGLE_HEIGHT, CROP_RECTANGLE_HEIGHT), *__pRectangleBitmap); //Right Rectangle + } + AppLogDebug("EXIT"); + return r; +} + +void +ImageCropForm::OnActionPerformed(const Tizen::Ui::Control& source, int actionId) +{ + SceneManager* pSceneManager = SceneManager::GetInstance(); + switch(actionId) + { + case IDA_BUTTON_CANCEL: + pSceneManager->GoBackward(BackwardSceneTransition()); + break; + case IDA_BUTTON_SAVE: + { + ImageBuffer* pCropbuffer = null; + pCropbuffer = __imageBuffer.CropN(((__cropBox.x - __imageBox.x) * __imageWidth) / __imageBox.width, ((__cropBox.y - __imageBox.y) * __imageHeight) / __imageBox.height, + (__cropBox.width * __imageWidth) / __imageBox.width, (__cropBox.height * __imageHeight) / __imageBox.height); + pCropbuffer->EncodeToFile(__destFilePath, __imageFormat, true, 100); + delete pCropbuffer; + + pSceneManager->GoBackward(BackwardSceneTransition()); + AppLog("Exit"); + } + break; + } +} + +void +ImageCropForm::OnTouchPressed(const Tizen::Ui::Control& source, const Tizen::Graphics::Point& currentPosition, const Tizen::Ui::TouchEventInfo& touchInfo) +{ + AppLogDebug("ENTER"); + __touchStart = currentPosition; + CheckCurrentPosition(currentPosition); + AppLogDebug("EXIT"); +} + +void +ImageCropForm::OnTouchMoved(const Tizen::Ui::Control& source, const Tizen::Graphics::Point& currentPosition, const Tizen::Ui::TouchEventInfo& touchInfo) +{ + AppLogDebug("ENTER"); + if (__pointLocation == INSIDE_TOP_RECTANGLE) + { + int deltaY = currentPosition.y - __touchStart.y; + + if ((__cropBox.y + deltaY) > __imageBox.y) + { + if (__cropBox.height <= (CROP_RECTANGLE_HEIGHT * 2) && deltaY > 0) + { + __cropBox.height = (CROP_RECTANGLE_HEIGHT * 2); + } + else + { + __cropBox.y += deltaY; + __cropBox.height -= deltaY; + } + } + RequestRedraw(false); + } + else if (__pointLocation == INSIDE_BOTTOM_RECTANGLE) + { + int deltaY = currentPosition.y - __touchStart.y; + if ((__cropBox.y + __cropBox.height + deltaY ) < (__imageBox.y + __imageBox.height) && deltaY < __cropBox.height) + { + if (__cropBox.height <= (CROP_RECTANGLE_HEIGHT * 2) && deltaY < 0) + { + __cropBox.height = (CROP_RECTANGLE_HEIGHT * 2); + } + else + { + __cropBox.height += deltaY; + } + } + RequestRedraw(false); + } + else if (__pointLocation == INSIDE_LEFT_RECTANGLE) + { + int deltaX = currentPosition.x - __touchStart.x; + if ((__cropBox.x + deltaX) > __imageBox.x && deltaX < __cropBox.width) + { + if (__cropBox.width <= (CROP_RECTANGLE_HEIGHT * 2) && deltaX > 0) + { + __cropBox.width = (CROP_RECTANGLE_HEIGHT * 2); + } + else + { + __cropBox.x += deltaX; + __cropBox.width -= deltaX; + } + } + RequestRedraw(false); + } + else if (__pointLocation == INSIDE_RIGHT_RECTANGLE) + { + int deltaX = currentPosition.x - __touchStart.x; + if ((__cropBox.x + __cropBox.width + deltaX) < (__imageBox.x + __imageBox.width) && deltaX < __cropBox.width) + { + if (__cropBox.width <= (CROP_RECTANGLE_HEIGHT * 2) && deltaX < 0) + __cropBox.width = (CROP_RECTANGLE_HEIGHT * 2); + else + __cropBox.width += deltaX; + } + RequestRedraw(false); + } + else if (__pointLocation == INSIDE_CROPBOX) + { + int deltaX = currentPosition.x - __touchStart.x; + int deltaY = currentPosition.y - __touchStart.y; + if ((__cropBox.x + deltaX) > __imageBox.x) + { + __cropBox.x += deltaX; + } + else + { + __cropBox.x = __imageBox.x; + } + if ((__cropBox.y + deltaY) > __imageBox.y) + { + __cropBox.y += deltaY; + } + else + { + __cropBox.y = __imageBox.y; + } + if ((__cropBox.x + __cropBox.width + deltaX) > (__imageBox.x + __imageBox.width)) + { + __cropBox.x = __imageBox.x + __imageBox.width - __cropBox.width; + } + if ((__cropBox.y + __cropBox.height + deltaY) > (__imageBox.y + __imageBox.height)) + { + __cropBox.y = __imageBox.y + __imageBox.height - __cropBox.height; + } + RequestRedraw(false); + } + __touchStart = currentPosition; + AppLogDebug("EXIT"); +} + +void +ImageCropForm::OnTouchReleased(const Tizen::Ui::Control& source, const Tizen::Graphics::Point& currentPosition, const Tizen::Ui::TouchEventInfo& touchInfo) +{ + AppLogDebug("ENTER"); + __pointLocation = OUTSIDE_CROPBOX; + AppLogDebug("EXIT"); +} + +void +ImageCropForm::CheckCurrentPosition(const Point currentPosition) +{ + AppLogDebug("ENTER"); + if (currentPosition.x > ((__cropBox.x + __cropBox.width / 2) - (CROP_RECTANGLE_HEIGHT / 2)) && currentPosition.x < ((__cropBox.x + __cropBox.width / 2) + (CROP_RECTANGLE_HEIGHT / 2)) + && currentPosition.y > (__cropBox.y - (CROP_RECTANGLE_HEIGHT / 2)) && currentPosition.y < (__cropBox.y + (CROP_RECTANGLE_HEIGHT / 2))) + { + __pointLocation = INSIDE_TOP_RECTANGLE; + } + else if (currentPosition.x > (__cropBox.x - (CROP_RECTANGLE_HEIGHT / 2)) && currentPosition.x < (__cropBox.x + (CROP_RECTANGLE_HEIGHT / 2)) + && currentPosition.y > ((__cropBox.y + __cropBox.height / 2) - (CROP_RECTANGLE_HEIGHT / 2)) && currentPosition.y < ((__cropBox.y + __cropBox.height / 2) + (CROP_RECTANGLE_HEIGHT / 2))) + { + __pointLocation = INSIDE_LEFT_RECTANGLE; + } + else if (currentPosition.x > (__cropBox.x + __cropBox.width - (CROP_RECTANGLE_HEIGHT / 2)) && currentPosition.x < (__cropBox.x + __cropBox.width + (CROP_RECTANGLE_HEIGHT / 2)) + && currentPosition.y > ((__cropBox.y + __cropBox.height / 2) - (CROP_RECTANGLE_HEIGHT / 2)) && currentPosition.y < ((__cropBox.y + __cropBox.height / 2) + (CROP_RECTANGLE_HEIGHT / 2))) + { + __pointLocation = INSIDE_RIGHT_RECTANGLE; + } + else if (currentPosition.x > ((__cropBox.x + __cropBox.width / 2) - (CROP_RECTANGLE_HEIGHT / 2)) && currentPosition.x < ((__cropBox.x + __cropBox.width / 2) + (CROP_RECTANGLE_HEIGHT / 2)) + && currentPosition.y > (__cropBox.y + __cropBox.height - (CROP_RECTANGLE_HEIGHT / 2)) && currentPosition.y < (__cropBox.y + __cropBox.height + (CROP_RECTANGLE_HEIGHT / 2))) + { + __pointLocation = INSIDE_BOTTOM_RECTANGLE; + } + else if (currentPosition.x > __cropBox.x && currentPosition.x < (__cropBox.x + __cropBox.width) && currentPosition.y > __cropBox.y && currentPosition.y < (__cropBox.y + __cropBox.height)) + { + __pointLocation = INSIDE_CROPBOX; + } + else + { + __pointLocation = OUTSIDE_CROPBOX; + } + AppLogDebug("EXIT"); + return; +} diff --git a/src/IvImageSetterForm.cpp b/src/IvImageSetterForm.cpp index 4b8e986..305cbf6 100644 --- a/src/IvImageSetterForm.cpp +++ b/src/IvImageSetterForm.cpp @@ -57,7 +57,7 @@ ImageSetterForm::ImageSetterForm() , __statusValue(0) , __currentImageIndex(0) , __contentId(0) - , __currentBitmap(null) + , __pCurrentBitmap(null) , __pPresentationModel(null) { AppLogDebug("ENTER"); @@ -218,8 +218,8 @@ ImageSetterForm::CreateItem(int index) pBitmap = pImageBuffer.GetBitmapN(BITMAP_PIXEL_FORMAT_ARGB8888, BUFFER_SCALING_AUTO); } - __currentBitmap = pBitmap; - pGallery->Construct(*__currentBitmap, filePath); + __pCurrentBitmap = pBitmap; + pGallery->Construct(*__pCurrentBitmap, filePath); AppLogDebug("EXIT(%s)", GetErrorMessage(GetLastResult())); return pGallery; @@ -230,6 +230,7 @@ ImageSetterForm::DeleteItem(int index, GalleryItem* pItem) { AppLogDebug("ENTER"); delete pItem; + pItem = null; AppLogDebug("EXIT(%s)", GetErrorMessage(GetLastResult())); return true; @@ -267,9 +268,9 @@ result ImageSetterForm::OnTerminating(void) { AppLogDebug("ENTER"); - if (__currentBitmap != null) + if (__pCurrentBitmap != null) { - delete __currentBitmap; + delete __pCurrentBitmap; } AppLogDebug("EXIT(%s)", GetErrorMessage(GetLastResult())); @@ -296,7 +297,7 @@ ImageSetterForm::OnActionPerformed(const Control& source, int actionId) if (r == E_SUCCESS) { String destPath = App::GetInstance()->GetAppRootPath() + TEMP_FILE_PATH_HOME_SCREEN_WALLPAPER; - r = image.EncodeToFile(*__currentBitmap, IMG_FORMAT_JPG, destPath, true); + r = image.EncodeToFile(*__pCurrentBitmap, IMG_FORMAT_JPG, destPath, true); if (r == E_SUCCESS) { r = SettingInfo::SetValue(SETTING_VALUE_HOME_SCREEN_WALLPAPER, destPath); @@ -317,7 +318,7 @@ ImageSetterForm::OnActionPerformed(const Control& source, int actionId) if (r == E_SUCCESS) { String destPath = App::GetInstance()->GetAppRootPath() + TEMP_FILE_PATH_LOCK_SCREEN_WALLPAPER; - r = image.EncodeToFile(*__currentBitmap, IMG_FORMAT_JPG, destPath, true); + r = image.EncodeToFile(*__pCurrentBitmap, IMG_FORMAT_JPG, destPath, true); if (r == E_SUCCESS) { r = SettingInfo::SetValue(SETTING_VALUE_LOCK_SCREEN_WALLPAPER, destPath); diff --git a/src/IvImageViewerApp.cpp b/src/IvImageViewerApp.cpp index 7fae9de..496273e 100644 --- a/src/IvImageViewerApp.cpp +++ b/src/IvImageViewerApp.cpp @@ -209,6 +209,7 @@ ImageViewerApp::OnAppControlRequestReceived(RequestId reqId, const String& opera else { delete pArguments; + pArguments = null; } } AppLogDebug("EXIT(%s)", GetErrorMessage(GetLastResult())); diff --git a/src/IvImageViewerForm.cpp b/src/IvImageViewerForm.cpp index 0e7cde9..75b2f46 100644 --- a/src/IvImageViewerForm.cpp +++ b/src/IvImageViewerForm.cpp @@ -103,7 +103,6 @@ ImageViewerForm::ImageViewerForm(void) , __pDetailFooterItem(null) , __pGallery(null) , __pTimer(null) -, __pDecodeBitmap(null) , __pContextMenuMore(null) , __pContextMenuCopy(null) , __pContextMenuSetAs(null) @@ -192,9 +191,9 @@ ImageViewerForm::OnInitializing(void) InitializePanelDetail(); InitializePopup(); - if ( __initializeDisplayModeCurrent == APPCONTROL_MODE_NORMAL - || __initializeDisplayModeCurrent == APPCONTROL_MODE_MESSAGE - || __initializeDisplayModeCurrent == APPCONTROL_MODE_EMAIL) + if (__initializeDisplayModeCurrent == APPCONTROL_MODE_NORMAL + || __initializeDisplayModeCurrent == APPCONTROL_MODE_MESSAGE + || __initializeDisplayModeCurrent == APPCONTROL_MODE_EMAIL) { int index = __pPresentationModel->GetStartIndex(); __pGallery->UpdateGallery(); @@ -215,7 +214,6 @@ ImageViewerForm::OnInitializing(void) __pTimer->Construct(*this); __pTimer->Start(1); } - result r = SetActionBarsTranslucent(FORM_ACTION_BAR_INDICATOR, true); AddOrientationEventListener(*this); AppLogDebug("EXIT(%s)", GetErrorMessage(GetLastResult())); @@ -303,13 +301,13 @@ ImageViewerForm::InitializeDisplay(AppControlMode status) __pFooter->RemoveButtonAt(BUTTON_POSITION_LEFT); __pFooter->SetBackButton(); - FooterItem footerItem1; + FooterItem footerItem1; footerItem1.Construct(ACTION_ID_FOOTER_BUTTON_SHARE); Bitmap* pFooterItemShareNomal = ResourceManager::GetBitmapN(IDB_IMAGE_VIEWERFORM_FOOTER_ICON_SHARE_NORMAL); footerItem1.SetIcon(FOOTER_ITEM_STATUS_NORMAL, pFooterItemShareNomal); - FooterItem footerItem2; + FooterItem footerItem2; footerItem2.Construct(ACTION_ID_FOOTER_BUTTON_DELETE); Bitmap* pFooterItemDeleteNomal = ResourceManager::GetBitmapN(IDB_IMAGE_VIEWERFORM_FOOTER_ICON_DELETE_NORMAL); @@ -725,6 +723,7 @@ ImageViewerForm::InitializeContextMenuMore(void) { __pContextMenuMore->AddItem(ResourceManager::GetString(L"IDS_IV_OPT_SET_AS"), ACTION_ID_CONTEXTMENU_SET_AS); + __pContextMenuMore->AddItem("Crop", ACTION_ID_FOOTER_BUTTON_CROP); } if (__pGallery->GetItemCount() > 1) @@ -1355,6 +1354,15 @@ ImageViewerForm::OnActionPerformed(const Control& source, int actionId) } break; } + case ACTION_ID_FOOTER_BUTTON_CROP: + { + String filePath; + ArrayList* pList = new (std::nothrow) ArrayList(SingleObjectDeleter); + filePath = __pPresentationModel->GetFilePathAt(__pGallery->GetCurrentItemIndex()); + pList->Add(new (std::nothrow) String(filePath)); + pSceneManager->GoForward(ForwardSceneTransition(IDSCN_IMAGE_CROP), pList); + } + break; case ACTION_ID_FOOTER_BUTTON_DETAILS: { ShowPanelDetail(__detail); diff --git a/src/IvMainFrame.cpp b/src/IvMainFrame.cpp index 9589071..0f1707e 100644 --- a/src/IvMainFrame.cpp +++ b/src/IvMainFrame.cpp @@ -55,6 +55,7 @@ MainFrame::OnInitializing(void) pSceneManager->RegisterScene(IDSCN_IMAGE_VIEWER, FORM_IMAGE_VIEWER, PANEL_BLANK); pSceneManager->RegisterScene(IDSCN_IMAGE_SETTER, FORM_IMAGE_SETTER, PANEL_BLANK); + pSceneManager->RegisterScene(IDSCN_IMAGE_CROP, FORM_IMAGE_CROP, PANEL_BLANK); pSceneManager->RegisterScene(IDSCN_IMAGE_NAME_EDITOR, FORM_IMAGE_NAME_EDITOR, PANEL_BLANK); ImageViewerApp* pImageViewerApp = static_cast(ImageViewerApp::GetInstance()); diff --git a/src/IvTypes.cpp b/src/IvTypes.cpp index 3f2ac5a..32e56c2 100644 --- a/src/IvTypes.cpp +++ b/src/IvTypes.cpp @@ -26,13 +26,16 @@ const wchar_t* IDL_FORM_IMAGE_VIEWER = L"IDL_FORM_IMAGE_VIEWER"; const wchar_t* IDL_FORM_IMAGE_SETTER = L"IDL_FORM_IMAGE_SETTER"; const wchar_t* IDL_FORM_NAME_EDITOR = L"IDL_FORM_NAME_EDITOR"; +const wchar_t* IDL_FORM_IMAGE_CROP = L"IDL_FORM_IMAGE_CROP"; const wchar_t* FORM_IMAGE_VIEWER = L"ImageViewerForm"; const wchar_t* FORM_IMAGE_SETTER = L"ImageSetterForm"; +const wchar_t* FORM_IMAGE_CROP = L"ImageCropForm"; const wchar_t* FORM_IMAGE_NAME_EDITOR = L"ImageNameEditorForm"; const wchar_t* IDSCN_IMAGE_VIEWER = L"SceneImageView"; const wchar_t* IDSCN_IMAGE_SETTER = L"SceneImageSetterForm"; +const wchar_t* IDSCN_IMAGE_CROP = L"SceneImageCropForm"; const wchar_t* IDSCN_IMAGE_NAME_EDITOR = L"SceneImageNameEditorForm"; const wchar_t* APPCONTROL_PROVIDER_ID_MESSAGES = L"tizen.messages"; @@ -113,6 +116,12 @@ const wchar_t* IDB_IMAGE_VIEWERFORM_MORE_NORMAL = L"00_icon_more.png"; const wchar_t* IDB_IMAGE_VIEWERFORM_MORE_PRESSED = L"00_icon_more_press.png"; const wchar_t* IDB_IMAGE_VIEWERFORM_FOOTER_ICON_SHARE_NORMAL = L"T01_controlbar_icon_share02.png"; const wchar_t* IDB_IMAGE_VIEWERFORM_FOOTER_ICON_DELETE_NORMAL = L"T01_controlbar_icon_delete.png"; +const wchar_t* IDB_IMAGE_CROP_FORM_SAVE_ICON = L"T01-1_control_icon_save.png"; +const wchar_t* IDB_IMAGE_CROP_FORM_CANCEL_ICON = L"T01-1_control_icon_cancel.png"; +const wchar_t* IDB_IMAGE_CROP_FORM_CW_ROTATION_ICON = L"T01-1_control_icon_CW.png"; +const wchar_t* IDB_IMAGE_CROP_FORM_CCW_ROTATION_ICON = L"T01-1_control_icon_CCW.png"; +const wchar_t* IDB_IMAGE_CROP_FORM_ITEM_DIVIDER_ICON = L"T01_1_controlbar_bg.png"; +const wchar_t* IDB_IMAGE_CROP_RECTANGLE = L"T01-1_crop_rectangle.png"; const wchar_t* IDB_IMAGE_SETTERFORM_BUTTON_SET = L"T01_btn_SetCallerimage.png"; const wchar_t* IDB_IMAGE_SETTERFORM_BUTTON_SET_PRESS = L"T01_btn_SetCallerimage_press.png"; @@ -130,3 +139,7 @@ const wchar_t* ENTRY_NAME_IMAGE_VIEWER_SHUFFLE_VALUE = L"SHUFFLE_VALUE"; const wchar_t* DEVICE_STORAGE_CARD_MOUNTED = L"Mounted"; const wchar_t* DEVICE_STORAGE_CARD_UNMOUNTED = L"Unmounted"; + +const int FOOTER_PANEL_HEIGHT = 98; +const int INDICATOR_BAR_HEIGHT = 60; +const int CROP_RECTANGLE_HEIGHT = 20; -- 2.7.4