提交 bd613641 编写于 作者: H helsing.chen

IssueNo:https://gitee.com/openharmony/graphic_ui/issues/I3ZWVU

Description:add resize mode for ui_image_view
Sig:graphic
Feature or Bugfix:Feature
Binary Source:No:
Signed-off-by: Nhelsing.chen <helsing.chen@hisilicon.com>
上级 70dc5fcd
......@@ -243,6 +243,140 @@ UIImageView::~UIImageView()
#ifndef VERSION_LITE
RemoveAndStopGifAnimator();
#endif
if (drawTransMap_ != nullptr) {
delete drawTransMap_;
drawTransMap_ = nullptr;
}
if (contentMatrix_ != nullptr) {
delete contentMatrix_;
contentMatrix_ = nullptr;
}
}
void UIImageView::SetResizeMode(ImageResizeMode mode)
{
if (autoEnable_ || (imageResizeMode_ == mode)) {
return;
}
needRefresh_ = true;
ReMeasure();
imageResizeMode_ = mode;
UpdateDrawTransMap(true);
}
void UIImageView::UpdateContentMatrix()
{
Rect viewRect = GetOrigRect();
if ((imageResizeMode_ == ImageResizeMode::NONE) ||
(imageWidth_ == viewRect.GetWidth() && imageHeight_ == viewRect.GetHeight()) ||
imageWidth_ == 0 || imageHeight_ == 0) {
if (contentMatrix_ != nullptr) {
delete contentMatrix_;
contentMatrix_ = nullptr;
}
return;
}
// 2: the width should exclude the border-left and border-right, which equal borderwidth
int16_t widgetWidth = viewRect.GetWidth() -
style_->paddingLeft_ - style_->paddingRight_ - style_->borderWidth_ * 2;
// 2: the height should exclude the border-top and border-bottom, which equal borderwidth
int16_t widgetHeight = viewRect.GetHeight() -
style_->paddingTop_ - style_->paddingBottom_ - style_->borderWidth_ * 2;
float scaleX = static_cast<float>(widgetWidth) / static_cast<float>(imageWidth_);
float scaleY = static_cast<float>(widgetHeight) / static_cast<float>(imageHeight_);
if (contentMatrix_ == nullptr) {
contentMatrix_ = new Matrix3<float>();
if (contentMatrix_ == nullptr) {
GRAPHIC_LOGE("can not new contentMatrix");
return;
}
}
Vector2<int16_t> translate(style_->paddingLeft_ + style_->borderWidth_,
style_->paddingTop_ + style_->borderWidth_);
if (imageResizeMode_ == ImageResizeMode::CONTAIN) {
if (scaleX <= scaleY) {
scaleY = scaleX;
// 0.5: adjust the y-coordinate of the content to the center of widget
translate.y_ += (static_cast<float>(widgetHeight) - static_cast<float>(imageHeight_) * scaleX) * 0.5f;
} else {
scaleX = scaleY;
// 0.5: adjust the x-coordinate of the content to the center of widget
translate.x_ += (static_cast<float>(widgetWidth) - static_cast<float>(imageWidth_) * scaleY) * 0.5f;
}
}
auto scaleMatrix = Matrix3<float>::Scale(Vector2<float>(scaleX, scaleY),
Vector2<float>(GetOrigRect().GetX(), GetOrigRect().GetY()));
auto translateMatrix = Matrix3<float>::Translate(Vector2<float>(translate.x_, translate.y_));
*contentMatrix_ = translateMatrix * scaleMatrix;
}
void UIImageView::UpdateDrawTransMap(bool updateContentMatrix)
{
if (updateContentMatrix || (drawTransMap_ != nullptr &&
(drawTransMap_->GetTransMapRect().GetX() != GetOrigRect().GetX() ||
drawTransMap_->GetTransMapRect().GetY() != GetOrigRect().GetY()))) {
UpdateContentMatrix();
}
// has no transformation
if ((contentMatrix_ == nullptr) && ((transMap_ == nullptr) || transMap_->IsInvalid())) {
if (drawTransMap_ != nullptr) {
delete drawTransMap_;
drawTransMap_ = nullptr;
}
return;
}
if (drawTransMap_ == nullptr) {
drawTransMap_ = new TransformMap();
if (drawTransMap_ == nullptr) {
GRAPHIC_LOGE("can not new drawTransMap");
return;
}
}
auto viewRect = GetOrigRect();
if (contentMatrix_ != nullptr) {
drawTransMap_->SetTransMapRect(Rect(viewRect.GetX(), viewRect.GetY(),
viewRect.GetX() + imageWidth_ - 1, viewRect.GetY() + imageHeight_ - 1));
} else {
drawTransMap_->SetTransMapRect(viewRect);
}
// only contentMatrix
if (transMap_ == nullptr || transMap_->IsInvalid()) {
drawTransMap_->SetMatrix(*contentMatrix_);
return;
}
// update the transMap, now the transMap is not nullptr
if (!(transMap_->GetTransMapRect() == viewRect)) {
transMap_->SetTransMapRect(viewRect);
}
// only transMap
if (contentMatrix_ == nullptr) {
*drawTransMap_ = *transMap_;
return;
}
// merge the transMap and content matrix
auto rect = transMap_->GetTransMapRect();
auto translate = Matrix3<float>::Translate(Vector2<float>(-rect.GetX(), -rect.GetY()));
auto matrix = transMap_->GetTransformMatrix() * translate;
matrix = matrix * (*contentMatrix_);
drawTransMap_->SetMatrix(matrix);
}
void UIImageView::SetHeight(int16_t height)
{
if (GetHeight() != height) {
UIView::SetHeight(height);
UpdateDrawTransMap(true);
}
}
void UIImageView::SetWidth(int16_t width)
{
if (GetWidth() != width) {
UIView::SetWidth(width);
UpdateDrawTransMap(true);
}
}
bool UIImageView::OnPreDraw(Rect& invalidatedArea) const
......@@ -268,7 +402,7 @@ void UIImageView::OnDraw(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea)
if ((imageHeight_ == 0) || (imageWidth_ == 0)) {
return;
}
UpdateDrawTransMap();
Rect viewRect = GetContentRect();
Rect trunc(invalidatedArea);
if (trunc.Intersect(trunc, viewRect)) {
......@@ -278,7 +412,7 @@ void UIImageView::OnDraw(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea)
cordsTmp.SetTop(viewRect.GetY());
cordsTmp.SetBottom(viewRect.GetY() + imageHeight_ - 1);
if ((transMap_ == nullptr) || transMap_->IsInvalid()) {
if ((drawTransMap_ == nullptr) || drawTransMap_->IsInvalid()) {
while (cordsTmp.GetTop() <= viewRect.GetBottom()) {
cordsTmp.SetLeft(viewRect.GetX());
cordsTmp.SetRight(viewRect.GetX() + imageWidth_ - 1);
......@@ -290,7 +424,7 @@ void UIImageView::OnDraw(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea)
cordsTmp.SetTop(cordsTmp.GetTop() + imageHeight_);
cordsTmp.SetBottom(cordsTmp.GetBottom() + imageHeight_);
}
} else if ((transMap_ != nullptr) && !transMap_->IsInvalid()) {
} else if ((drawTransMap_ != nullptr) && !drawTransMap_->IsInvalid()) {
ImageInfo imgInfo;
if (srcType == IMG_SRC_FILE) {
CacheEntry entry;
......@@ -306,12 +440,9 @@ void UIImageView::OnDraw(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea)
TransformDataInfo imageTranDataInfo = {imgInfo.header, imgInfo.data, pxSize,
static_cast<BlurLevel>(blurLevel_),
static_cast<TransformAlgorithm>(algorithm_)};
Rect origRect = GetOrigRect();
transMap_->SetTransMapRect(origRect);
OpacityType opaScale = DrawUtils::GetMixOpacity(opa, style_->imageOpa_);
BaseGfxEngine::GetInstance()->DrawTransform(gfxDstBuffer, invalidatedArea, {0, 0}, Color::Black(),
opaScale, *transMap_, imageTranDataInfo);
opaScale, *drawTransMap_, imageTranDataInfo);
}
}
}
......
......@@ -157,6 +157,9 @@ public:
void SetAutoEnable(bool enable)
{
if (autoEnable_ != enable) {
if (enable) {
SetResizeMode(ImageResizeMode::NONE);
}
needRefresh_ = autoEnable_ ? needRefresh_ : true;
autoEnable_ = enable;
}
......@@ -259,6 +262,16 @@ public:
return image_.GetSrcType();
}
enum ImageResizeMode : uint8_t {
NONE,
FILL,
CONTAIN,
};
void SetResizeMode(ImageResizeMode mode);
void SetWidth(int16_t width) override;
void SetHeight(int16_t height) override;
protected:
/**
* @brief Represents the width of this image.
......@@ -290,7 +303,10 @@ protected:
uint8_t algorithm_ : 1;
uint8_t reserve_ : 1;
Image image_;
ImageResizeMode imageResizeMode_ = ImageResizeMode::NONE;
TransformMap* drawTransMap_ = nullptr;
Matrix3<float>* contentMatrix_ = nullptr;
bool transMapInvalid_ = true;
private:
void ReMeasure() override;
#ifndef VERSION_LITE
......@@ -300,6 +316,8 @@ private:
Animator* gifImageAnimator_;
bool gifFrameFlag_;
#endif
void UpdateContentMatrix();
void UpdateDrawTransMap(bool updateContentMatrix = false);
};
} // namespace OHOS
#endif // GRAPHIC_LITE_UI_IMAGE_VIEW_H
\ No newline at end of file
......@@ -74,6 +74,7 @@ const UIView* UITestImage::GetTestView()
UIKit_UIImage_Test_SetImage_016();
#endif
UIKit_UIImage_Test_Uncompress_001();
UIKit_UIImage_Test_Resize_001();
return container_;
}
......@@ -512,7 +513,51 @@ void UITestImage::UIKit_UIImage_Test_Uncompress_001()
container_->Add(imageView1);
container_->Add(imageView2);
container_->Add(imageView3);
g_height += 100; // offset=100
g_height += 150; // offset=150
}
}
UILabel* UITestImage::AddLable(int16_t x, int16_t y, const char* data)
{
UILabel* label = new UILabel();
container_->Add(label);
label->SetPosition(x, y, Screen::GetInstance().GetWidth(),
TITLE_LABEL_DEFAULT_HEIGHT);
label->SetText(data);
label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE);
return label;
}
UIImageView* UITestImage::AddImageView(const Rect rect, const char* src, bool autoEnable,
UIImageView::ImageResizeMode mode)
{
UIImageView* imageView = new UIImageView();
imageView->SetAutoEnable(autoEnable);
imageView->SetPosition(rect.GetX(), rect.GetY(), rect.GetWidth(), rect.GetHeight());
imageView->SetSrc(src);
imageView->SetResizeMode(mode);
container_->Add(imageView);
}
void UITestImage::UIKit_UIImage_Test_Resize_001()
{
if (container_ != nullptr) {
AddLable(TEXT_DISTANCE_TO_LEFT_SIDE, g_height, "图片缩放模式测试");
AddLable(48, g_height + 30, "Fill mode"); // 48: position x; 30: increase y-coordinate
AddLable(160, g_height + 30, "Contain mode"); // 160: position x; 30: increase y-coordinate
AddLable(320, g_height + 30, "Auto mode"); // 320: position x; 30: increase y-coordinate
AddLable(480, g_height + 30, "Tiling mode"); // 480: position x; 30: increase y-coordinate
UIImageView* imageView;
// 48: position x; 70: increase y-coordinate; 100: width and height
AddImageView(GetRect(48, g_height + 70, 100, 100), RED_IMAGE_PATH, false, UIImageView::ImageResizeMode::FILL);
// 160: position x; 70: increase y-coordinate; 100: width and height
AddImageView(GetRect(160, g_height + 70, 100, 50), RED_IMAGE_PATH,
false, UIImageView::ImageResizeMode::CONTAIN);
// 320: position x; 70: increase y-coordinate; 100: width and height
AddImageView(GetRect(320, g_height + 70, 100, 100), RED_IMAGE_PATH, true, UIImageView::ImageResizeMode::NONE);
// 480: position x; 70: increase y-coordinate; 100: width and height
AddImageView(GetRect(480, g_height + 70, 100, 100), RED_IMAGE_PATH, false, UIImageView::ImageResizeMode::NONE);
g_height += 150; // offset 150
}
}
} // namespace OHOS
......@@ -19,9 +19,9 @@
#include "components/ui_scroll_view.h"
#include "imgdecode/cache_manager.h"
#include "ui_test.h"
#include "components/ui_image_view.h"
#ifndef VERSION_LITE
#include "components/ui_image_view.h"
#include "components/ui_label_button.h"
#include "test_resource_config.h"
#endif
......@@ -56,7 +56,7 @@ public:
void UIKit_UIImage_Test_SetImage_016();
#endif
void UIKit_UIImage_Test_Uncompress_001();
void UIKit_UIImage_Test_Resize_001();
private:
const char* GetCharByImageSrcType(ImageSrcType srcType) const;
#ifndef VERSION_LITE
......@@ -74,6 +74,13 @@ private:
UILabelButton* gifToBin03_ = nullptr;
UILabelButton* gifToBin04_ = nullptr;
#endif
private:
UILabel* AddLable(int16_t x, int16_t y, const char* data);
UIImageView* AddImageView(const Rect rect, const char* src, bool autoEnable, UIImageView::ImageResizeMode mode);
Rect GetRect(int16_t x, int16_t y, int16_t w, int16_t h) const
{
return Rect(x, y, x + w , y + h);
}
};
} // namespace OHOS
#endif // UI_TEST_IMAGE_H
......@@ -58,6 +58,19 @@ void UITestTransform::SetUp()
layout_->SetRows(3); // 3:two rows
layout_->SetCols(1); // 1:three cols
}
AddLable(layout_->GetOrigRect().GetRight() + 34, 50, "Auto"); // 34 : increase x-coordinate; 50: position y
AddLable(layout_->GetOrigRect().GetRight() + 34, 100, "Fill"); // 34 : increase x-coordinate; 100: position y
AddLable(layout_->GetOrigRect().GetRight() + 34, 150, "Contain"); // 34 : increase x-coordinate; 150: position y
AddLable(layout_->GetOrigRect().GetRight() + 34, 200, "Tiling"); // 34 : increase x-coordinate; 200: position y
AddRadioButton(GetRect(560, 40, 50, 50), // 560:position x 40:position y 50:width and height
"RB", new StateChangeListener(ImageScaleMode::AUTO, this))->SetState(
UICheckBox::UICheckBoxState::SELECTED);
AddRadioButton(GetRect(560, 90, 50, 50), // 560:position x 90:position y 50:width and height
"RB", new StateChangeListener(ImageScaleMode::FILL, this));
AddRadioButton(GetRect(560, 140, 50, 50), // 560:position x 90:position y 50:width and height
"RB", new StateChangeListener(ImageScaleMode::CONTAIN, this));
AddRadioButton(GetRect(560, 190, 50, 50), // 560:position x 90:position y 50:width and height
"RB", new StateChangeListener(ImageScaleMode::TILING, this));
}
void UITestTransform::TearDown()
......@@ -119,16 +132,123 @@ bool UITestTransform::OnClick(UIView& view, const ClickEvent& event)
{
Rect viewRect = imageView_->GetOrigRect();
TransformMap transMap(viewRect);
Vector2<float> pivot_(58, 58); // 58:x value 58:y value
Vector2<float> pivot(58, 58); // 58:x value 58:y value
if (&view == rotateBtn_) {
transMap.Rotate(90, pivot_); // 90:degree
angle_ = (angle_ + 90) % 360; // 90: increase angle; 360: wrapping value
} else if (&view == scaleBtn_) {
transMap.Scale(Vector2<float>(1.5, 1.5), pivot_); // 1.5:x scale 1.5:y scale
scale_ += 0.1f; // 0.1: increase scale
} else if (&view == translateBtn_) {
transMap.Translate(Vector2<int16_t>(80, -30)); // 80:x-axis translation distance -30:y-axis translation distance
trans_ += 10; // 10: increase translate
}
SetTransMap(angle_, scale_, trans_, pivot);
return true;
}
void UITestTransform::SetScaleMode(ImageScaleMode mode)
{
// must the position fisrt
switch (mode) {
case ImageScaleMode::AUTO:
imageView_->SetAutoEnable(true);
imageView_->SetResizeMode(UIImageView::ImageResizeMode::NONE);
break;
case ImageScaleMode::CONTAIN:
imageView_->SetAutoEnable(false);
imageView_->SetResizeMode(UIImageView::ImageResizeMode::CONTAIN);
break;
case ImageScaleMode::FILL:
imageView_->SetAutoEnable(false);
imageView_->SetResizeMode(UIImageView::ImageResizeMode::FILL);
break;
case ImageScaleMode::TILING:
imageView_->SetAutoEnable(false);
imageView_->SetResizeMode(UIImageView::ImageResizeMode::NONE);
break;
default:
break;
}
if (mode != ImageScaleMode::AUTO) {
imageView_->SetWidth(200); // 200: width
imageView_->SetHeight(200); // 200: height
}
// reset the transmap
SetTransMap(0, 1.0f, 0, {0.0f, 0.0f});
uiViewGroupFrame_->Invalidate();
}
void UITestTransform::SetTransMap(int16_t angle, float scale, int16_t trans, Vector2<float> pivot)
{
angle_ = angle;
scale_ = scale;
trans_ = trans;
Rect viewRect = imageView_->GetOrigRect();
TransformMap transMap(viewRect);
transMap.Rotate(angle_, pivot);
transMap.Scale(Vector2<float>(scale_, scale_), pivot);
transMap.Translate(Vector2<int16_t>(trans, 0));
imageView_->SetTransformMap(transMap);
}
return true;
UILabel* UITestTransform::AddLable(int16_t x, int16_t y, const char* data)
{
UILabel* label = new UILabel();
container_->Add(label);
label->SetPosition(x, y, Screen::GetInstance().GetWidth(),
TITLE_LABEL_DEFAULT_HEIGHT);
label->SetText(data);
label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE);
return label;
}
UIRadioButton* UITestTransform::AddRadioButton(Rect rect, const char* name, UICheckBox::OnChangeListener* listener)
{
if (listener == nullptr || name == nullptr) {
return nullptr;
}
auto radioButton = new UITestRadioButton("dddd");
container_->Add(radioButton);
radioButton->SetOnChangeListener(listener);
radioButton->SetPosition(rect.GetX(), rect.GetY(), rect.GetWidth(), rect.GetHeight());
if (radioButton->GetState() == UICheckBox::SELECTED) {
listener->OnChange(UICheckBox::SELECTED);
}
return radioButton;
}
StateChangeListener::StateChangeListener(ImageScaleMode mode, UITestTransform* testInstance)
: mode_(mode),
testInstance_(testInstance)
{
}
bool StateChangeListener::OnChange(UICheckBox::UICheckBoxState state)
{
if (state == UICheckBox::UICheckBoxState::SELECTED) {
testInstance_->SetScaleMode(mode_);
}
}
UITestRadioButton::UITestRadioButton(const char* name)
: UIRadioButton(name)
{
}
UITestRadioButton::~UITestRadioButton()
{
if (listener_ != nullptr) {
delete listener_;
listener_ = nullptr;
}
}
void UITestRadioButton::SetOnChangeListener(UICheckBox::OnChangeListener* listener)
{
UIRadioButton::SetOnChangeListener(listener);
if (listener_ != nullptr) {
delete listener_;
}
listener_ = listener;
}
} // namespace OHOS
\ No newline at end of file
......@@ -20,10 +20,19 @@
#include "components/ui_label.h"
#include "components/ui_label_button.h"
#include "components/ui_scroll_view.h"
#include "components/ui_checkbox.h"
#include "components/ui_radio_button.h"
#include "layout/grid_layout.h"
#include "ui_test.h"
namespace OHOS {
enum ImageScaleMode {
FILL,
AUTO,
CONTAIN,
TILING,
};
class UITestTransform : public UITest, public UIView::OnClickListener {
public:
UITestTransform() {}
......@@ -40,7 +49,16 @@ public:
void UIKit_Transform_Test_Scale_002();
void UIKit_Transform_Test_Translate_003();
void SetScaleMode(ImageScaleMode mode);
private:
UILabel* AddLable(int16_t x, int16_t y, const char* data);
UIRadioButton* AddRadioButton(Rect rect, const char* name, UICheckBox::OnChangeListener* listener);
Rect GetRect(int16_t x, int16_t y, int16_t w, int16_t h) const
{
return Rect(x, y, x + w - 1, y + h - 1);
}
void SetTransMap(int16_t angle, float scale, int16_t trans, Vector2<float> pivot);
UIScrollView* container_ = nullptr;
GridLayout* layout_ = nullptr;
UIImageView* imageView_ = nullptr;
......@@ -49,6 +67,28 @@ private:
UILabelButton* rotateBtn_ = nullptr;
UILabelButton* scaleBtn_ = nullptr;
UILabelButton* translateBtn_ = nullptr;
int16_t angle_ = 0;
float scale_ = 1.0;
int16_t trans_ = 0;
};
class StateChangeListener : public UICheckBox::OnChangeListener {
public:
explicit StateChangeListener(ImageScaleMode mode, UITestTransform* testInstance_);
~StateChangeListener() {}
bool OnChange(UICheckBox::UICheckBoxState state) override;
private:
ImageScaleMode mode_ = ImageScaleMode::AUTO;
UITestTransform* testInstance_ = nullptr;
};
class UITestRadioButton : public UIRadioButton {
public:
explicit UITestRadioButton(const char* name);
~UITestRadioButton();
void SetOnChangeListener(UICheckBox::OnChangeListener* listener);
private:
UICheckBox::OnChangeListener* listener_ = nullptr;
};
} // namespace OHOS
#endif // UI_TEST_TRANSFORM_H
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册