#include "HGImgThumb.h" #include #include #include #include #include #include #include #include #include #include #include "base/HGInc.h" #include "base/HGUtility.h" #include "imgfmt/HGImgFmt.h" #include "HGUIGlobal.h" HGImgThumb::HGImgThumb(QWidget* parent) : QWidget(parent) { HGBase_CreateLock(&m_lockFront); HGBase_CreateLock(&m_lockBack); HGBase_CreateLock(&m_lockItemSize); HGBase_CreateEvent(HGFALSE, HGFALSE, &m_event); m_gapSize = 10; m_scrollSize = 10; m_minScrollSliderSize = 8; m_itemSize = 120; m_itemTextHeight = 20; m_defItemImage = nullptr; m_itemImage = nullptr; for (int i = 0; i < 3; ++i) { m_hScrollLeftImage[i] = nullptr; m_hScrollRightImage[i] = nullptr; m_vScrollTopImage[i] = nullptr; m_vScrollBottomImage[i] = nullptr; m_hScrollSliderImage[i] = nullptr; m_vScrollSliderImage[i] = nullptr; } m_hScrollImage = nullptr; m_vScrollImage = nullptr; m_nullScrollImage = nullptr; m_type = ThumbType_Grid; m_mouseOn = false; m_curItemIndex = -1; m_hotItemIndex = -1; m_pushItemIndex = -1; m_signItemIndex = -1; m_stopThread = false; HGBase_OpenThread(ThreadFunc, this, &m_thread); m_hScroll = false; m_vScroll = false; m_showThumb = false; memset(&m_thumbRect, 0, sizeof(ThumbRect)); m_mouseMoveStatus = MouseStatus_Null; m_mousePressStatus = MouseStatus_Null; m_mousePressBeginX = -1; m_mousePressBeginY = -1; m_hitMouseButtons = Qt::NoButton; m_hitKeyboardModifiers = Qt::NoModifier; m_hitItemIndex = -1; m_operate = 0; m_operateStartX = -1; m_operateStartY = -1; m_draging = false; m_insertPtValid = false; m_curInsertPos = -1; m_frameSelection = false; m_frameSelectionRectValid = false; setFocusPolicy(Qt::ClickFocus); setMouseTracking(true); setAcceptDrops(true); connect(this, SIGNAL(updateItem()), this, SLOT(on_updateItem()), Qt::QueuedConnection); } HGImgThumb::~HGImgThumb() { removeAllItems(ThumbRemoveFlag::ThumbRemoveFlag_NULL); m_stopThread = true; HGBase_SetEvent(m_event); HGBase_CloseThread(m_thread); m_thread = nullptr; delete m_hScrollImage; m_hScrollImage = nullptr; delete m_vScrollImage; m_vScrollImage = nullptr; delete m_nullScrollImage; m_nullScrollImage = nullptr; for (int i = 0; i < 3; ++i) { delete m_hScrollLeftImage[i]; m_hScrollLeftImage[i] = nullptr; delete m_hScrollRightImage[i]; m_hScrollRightImage[i] = nullptr; delete m_vScrollTopImage[i]; m_vScrollTopImage[i] = nullptr; delete m_vScrollBottomImage[i]; m_vScrollBottomImage[i] = nullptr; delete m_hScrollSliderImage[i]; m_hScrollSliderImage[i] = nullptr; delete m_vScrollSliderImage[i]; m_vScrollSliderImage[i] = nullptr; } delete m_itemImage; m_itemImage = nullptr; delete m_defItemImage; m_defItemImage = nullptr; HGBase_DestroyEvent(m_event); m_event = nullptr; HGBase_DestroyLock(m_lockItemSize); m_lockItemSize = nullptr; HGBase_DestroyLock(m_lockBack); m_lockBack = nullptr; HGBase_DestroyLock(m_lockFront); m_lockFront = nullptr; qDebug("~HGImgThumb"); } HGResult HGImgThumb::setGapSize(int size) { if (MouseStatus_Null != m_mousePressStatus || 0 != m_operate || m_draging || m_frameSelection) { return HGBASE_ERR_FAIL; } if (size < 0 || size > 40) { return HGBASE_ERR_INVALIDARG; } if (0 != m_frontItems.size()) { return HGBASE_ERR_FAIL; } m_gapSize = size; return HGBASE_ERR_OK; } HGResult HGImgThumb::setScrollSize(int size) { if (MouseStatus_Null != m_mousePressStatus || 0 != m_operate || m_draging || m_frameSelection) { return HGBASE_ERR_FAIL; } if (size < 10 || size > 20) { return HGBASE_ERR_INVALIDARG; } if (0 != m_frontItems.size()) { return HGBASE_ERR_FAIL; } m_scrollSize = size; return HGBASE_ERR_OK; } HGResult HGImgThumb::setMinScrollSliderSize(int size) { if (MouseStatus_Null != m_mousePressStatus || 0 != m_operate || m_draging || m_frameSelection) { return HGBASE_ERR_FAIL; } if (size < 8 || size > 64) { return HGBASE_ERR_INVALIDARG; } if (0 != m_frontItems.size()) { return HGBASE_ERR_FAIL; } m_minScrollSliderSize = size; return HGBASE_ERR_OK; } HGResult HGImgThumb::setItemSize(int size) { if (MouseStatus_Null != m_mousePressStatus || 0 != m_operate || m_draging || m_frameSelection) { return HGBASE_ERR_FAIL; } if (size < 60 || size > 240) { return HGBASE_ERR_INVALIDARG; } if (0 != m_frontItems.size()) { return HGBASE_ERR_FAIL; } if (m_itemSize == size) { return HGBASE_ERR_OK; } HGBase_EnterLock(m_lockItemSize); m_itemSize = size; HGBase_LeaveLock(m_lockItemSize); if (nullptr != m_defItemImage) { assert(nullptr != m_itemImage); delete m_itemImage; m_itemImage = createItemImage(m_defItemImage, m_itemSize); assert(nullptr != m_itemImage); } return HGBASE_ERR_OK; } HGResult HGImgThumb::setItemTextHeight(int height) { if (MouseStatus_Null != m_mousePressStatus || 0 != m_operate || m_draging || m_frameSelection) { return HGBASE_ERR_FAIL; } if (height < 0 || height > 40) { return HGBASE_ERR_INVALIDARG; } if (0 != m_frontItems.size()) { return HGBASE_ERR_FAIL; } m_itemTextHeight = height; return HGBASE_ERR_OK; } HGResult HGImgThumb::setDefItemImage(const QImage *image) { if (MouseStatus_Null != m_mousePressStatus || 0 != m_operate || m_draging || m_frameSelection) { return HGBASE_ERR_FAIL; } if (0 != m_frontItems.size()) { return HGBASE_ERR_FAIL; } if (nullptr == image) { delete m_itemImage; m_itemImage = nullptr; delete m_defItemImage; m_defItemImage = nullptr; return HGBASE_ERR_OK; } QImage *img = new QImage(*image); if (img->isNull()) { delete img; return HGBASE_ERR_FAIL; } if (nullptr != m_defItemImage) { assert(nullptr != m_itemImage); delete m_itemImage; delete m_defItemImage; } else { assert(nullptr == m_itemImage); } m_defItemImage = img; m_itemImage = createItemImage(m_defItemImage, m_itemSize); assert(nullptr != m_itemImage); return HGBASE_ERR_OK; } HGResult HGImgThumb::setHScrollLeftImage(const QImage *normalImage, const QImage *hotImage, const QImage *pushImage) { if (MouseStatus_Null != m_mousePressStatus || 0 != m_operate || m_draging || m_frameSelection) { return HGBASE_ERR_FAIL; } if (0 != m_frontItems.size()) { return HGBASE_ERR_FAIL; } if (nullptr == normalImage) { delete m_hScrollLeftImage[0]; m_hScrollLeftImage[0] = nullptr; } else { QImage *img = new QImage(*normalImage); if (!img->isNull()) { if (nullptr != m_hScrollLeftImage[0]) delete m_hScrollLeftImage[0]; m_hScrollLeftImage[0] = img; } else { delete img; } } if (nullptr == hotImage) { delete m_hScrollLeftImage[1]; m_hScrollLeftImage[1] = nullptr; } else { QImage *img = new QImage(*hotImage); if (!img->isNull()) { if (nullptr != m_hScrollLeftImage[1]) delete m_hScrollLeftImage[1]; m_hScrollLeftImage[1] = img; } else { delete img; } } if (nullptr == pushImage) { delete m_hScrollLeftImage[2]; m_hScrollLeftImage[2] = nullptr; } else { QImage *img = new QImage(*pushImage); if (!img->isNull()) { if (nullptr != m_hScrollLeftImage[2]) delete m_hScrollLeftImage[2]; m_hScrollLeftImage[2] = img; } else { delete img; } } return HGBASE_ERR_OK; } HGResult HGImgThumb::setHScrollRightImage(const QImage *normalImage, const QImage *hotImage, const QImage *pushImage) { if (MouseStatus_Null != m_mousePressStatus || 0 != m_operate || m_draging || m_frameSelection) { return HGBASE_ERR_FAIL; } if (0 != m_frontItems.size()) { return HGBASE_ERR_FAIL; } if (nullptr == normalImage) { delete m_hScrollRightImage[0]; m_hScrollRightImage[0] = nullptr; } else { QImage *img = new QImage(*normalImage); if (!img->isNull()) { if (nullptr != m_hScrollRightImage[0]) delete m_hScrollRightImage[0]; m_hScrollRightImage[0] = img; } else { delete img; } } if (nullptr == hotImage) { delete m_hScrollRightImage[1]; m_hScrollRightImage[1] = nullptr; } else { QImage *img = new QImage(*hotImage); if (!img->isNull()) { if (nullptr != m_hScrollRightImage[1]) delete m_hScrollRightImage[1]; m_hScrollRightImage[1] = img; } else { delete img; } } if (nullptr == pushImage) { delete m_hScrollRightImage[2]; m_hScrollRightImage[2] = nullptr; } else { QImage *img = new QImage(*pushImage); if (!img->isNull()) { if (nullptr != m_hScrollRightImage[2]) delete m_hScrollRightImage[2]; m_hScrollRightImage[2] = img; } else { delete img; } } return HGBASE_ERR_OK; } HGResult HGImgThumb::setVScrollTopImage(const QImage *normalImage, const QImage *hotImage, const QImage *pushImage) { if (MouseStatus_Null != m_mousePressStatus || 0 != m_operate || m_draging || m_frameSelection) { return HGBASE_ERR_FAIL; } if (0 != m_frontItems.size()) { return HGBASE_ERR_FAIL; } if (nullptr == normalImage) { delete m_vScrollTopImage[0]; m_vScrollTopImage[0] = nullptr; } else { QImage *img = new QImage(*normalImage); if (!img->isNull()) { if (nullptr != m_vScrollTopImage[0]) delete m_vScrollTopImage[0]; m_vScrollTopImage[0] = img; } else { delete img; } } if (nullptr == hotImage) { delete m_vScrollTopImage[1]; m_vScrollTopImage[1] = nullptr; } else { QImage *img = new QImage(*hotImage); if (!img->isNull()) { if (nullptr != m_vScrollTopImage[1]) delete m_vScrollTopImage[1]; m_vScrollTopImage[1] = img; } else { delete img; } } if (nullptr == pushImage) { delete m_vScrollTopImage[2]; m_vScrollTopImage[2] = nullptr; } else { QImage *img = new QImage(*pushImage); if (!img->isNull()) { if (nullptr != m_vScrollTopImage[2]) delete m_vScrollTopImage[2]; m_vScrollTopImage[2] = img; } else { delete img; } } return HGBASE_ERR_OK; } HGResult HGImgThumb::setVScrollBottomImage(const QImage *normalImage, const QImage *hotImage, const QImage *pushImage) { if (MouseStatus_Null != m_mousePressStatus || 0 != m_operate || m_draging || m_frameSelection) { return HGBASE_ERR_FAIL; } if (0 != m_frontItems.size()) { return HGBASE_ERR_FAIL; } if (nullptr == normalImage) { delete m_vScrollBottomImage[0]; m_vScrollBottomImage[0] = nullptr; } else { QImage *img = new QImage(*normalImage); if (!img->isNull()) { if (nullptr != m_vScrollBottomImage[0]) delete m_vScrollBottomImage[0]; m_vScrollBottomImage[0] = img; } else { delete img; } } if (nullptr == hotImage) { delete m_vScrollBottomImage[1]; m_vScrollBottomImage[1] = nullptr; } else { QImage *img = new QImage(*hotImage); if (!img->isNull()) { if (nullptr != m_vScrollBottomImage[1]) delete m_vScrollBottomImage[1]; m_vScrollBottomImage[1] = img; } else { delete img; } } if (nullptr == pushImage) { delete m_vScrollBottomImage[2]; m_vScrollBottomImage[2] = nullptr; } else { QImage *img = new QImage(*pushImage); if (!img->isNull()) { if (nullptr != m_vScrollBottomImage[2]) delete m_vScrollBottomImage[2]; m_vScrollBottomImage[2] = img; } else { delete img; } } return HGBASE_ERR_OK; } HGResult HGImgThumb::setHScrollImage(const QImage *image, const HGRect *stretch) { if (MouseStatus_Null != m_mousePressStatus || 0 != m_operate || m_draging || m_frameSelection) { return HGBASE_ERR_FAIL; } if (0 != m_frontItems.size()) { return HGBASE_ERR_FAIL; } if (nullptr == image) { delete m_hScrollImage; m_hScrollImage = nullptr; } else { QImage *img = new QImage(*image); if (!img->isNull()) { if (nullptr != m_hScrollImage) delete m_hScrollImage; m_hScrollImage = img; if (nullptr == stretch || stretch->left < 0 || stretch->top < 0 || stretch->right > m_hScrollImage->width() || stretch->bottom > m_hScrollImage->height() || stretch->left >= stretch->right || stretch->top >= stretch->bottom) { m_hScrollImageStretch.setX(0); m_hScrollImageStretch.setY(0); m_hScrollImageStretch.setWidth(m_hScrollImage->width()); m_hScrollImageStretch.setHeight(m_hScrollImage->height()); } else { m_hScrollImageStretch.setX(stretch->left); m_hScrollImageStretch.setY(stretch->top); m_hScrollImageStretch.setWidth(stretch->right - stretch->left); m_hScrollImageStretch.setHeight(stretch->bottom - stretch->top); } } else { delete img; } } return HGBASE_ERR_OK; } HGResult HGImgThumb::setHScrollSliderImage(const QImage *normalImage, const HGRect *normalStretch, const QImage *hotImage, const HGRect *hotStretch, const QImage *pushImage, const HGRect *pushStretch) { if (MouseStatus_Null != m_mousePressStatus || 0 != m_operate || m_draging || m_frameSelection) { return HGBASE_ERR_FAIL; } if (0 != m_frontItems.size()) { return HGBASE_ERR_FAIL; } if (nullptr == normalImage) { delete m_hScrollSliderImage[0]; m_hScrollSliderImage[0] = nullptr; } else { QImage *img = new QImage(*normalImage); if (!img->isNull()) { if (nullptr != m_hScrollSliderImage[0]) delete m_hScrollSliderImage[0]; m_hScrollSliderImage[0] = img; if (nullptr == normalStretch || normalStretch->left < 0 || normalStretch->top < 0 || normalStretch->right > m_hScrollSliderImage[0]->width() || normalStretch->bottom > m_hScrollSliderImage[0]->height() || normalStretch->left >= normalStretch->right || normalStretch->top >= normalStretch->bottom) { m_hScrollSliderImageStretch[0].setX(0); m_hScrollSliderImageStretch[0].setY(0); m_hScrollSliderImageStretch[0].setWidth(m_hScrollSliderImage[0]->width()); m_hScrollSliderImageStretch[0].setHeight(m_hScrollSliderImage[0]->height()); } else { m_hScrollSliderImageStretch[0].setX(normalStretch->left); m_hScrollSliderImageStretch[0].setY(normalStretch->top); m_hScrollSliderImageStretch[0].setWidth(normalStretch->right - normalStretch->left); m_hScrollSliderImageStretch[0].setHeight(normalStretch->bottom - normalStretch->top); } } else { delete img; } } if (nullptr == hotImage) { delete m_hScrollSliderImage[1]; m_hScrollSliderImage[1] = nullptr; } else { QImage *img = new QImage(*hotImage); if (!img->isNull()) { if (nullptr != m_hScrollSliderImage[1]) delete m_hScrollSliderImage[1]; m_hScrollSliderImage[1] = img; if (nullptr == hotStretch || hotStretch->left < 0 || hotStretch->top < 0 || hotStretch->right > m_hScrollSliderImage[1]->width() || hotStretch->bottom > m_hScrollSliderImage[1]->height() || hotStretch->left >= hotStretch->right || hotStretch->top >= hotStretch->bottom) { m_hScrollSliderImageStretch[1].setX(0); m_hScrollSliderImageStretch[1].setY(0); m_hScrollSliderImageStretch[1].setWidth(m_hScrollSliderImage[1]->width()); m_hScrollSliderImageStretch[1].setHeight(m_hScrollSliderImage[1]->height()); } else { m_hScrollSliderImageStretch[1].setX(hotStretch->left); m_hScrollSliderImageStretch[1].setY(hotStretch->top); m_hScrollSliderImageStretch[1].setWidth(hotStretch->right - hotStretch->left); m_hScrollSliderImageStretch[1].setHeight(hotStretch->bottom - hotStretch->top); } } else { delete img; } } if (nullptr == pushImage) { delete m_hScrollSliderImage[2]; m_hScrollSliderImage[2] = nullptr; } else { QImage *img = new QImage(*pushImage); if (!img->isNull()) { if (nullptr != m_hScrollSliderImage[2]) delete m_hScrollSliderImage[2]; m_hScrollSliderImage[2] = img; if (nullptr == pushStretch || pushStretch->left < 0 || pushStretch->top < 0 || pushStretch->right > m_hScrollSliderImage[2]->width() || pushStretch->bottom > m_hScrollSliderImage[2]->height() || pushStretch->left >= pushStretch->right || pushStretch->top >= hotStretch->bottom) { m_hScrollSliderImageStretch[2].setX(0); m_hScrollSliderImageStretch[2].setY(0); m_hScrollSliderImageStretch[2].setWidth(m_hScrollSliderImage[2]->width()); m_hScrollSliderImageStretch[2].setHeight(m_hScrollSliderImage[2]->height()); } else { m_hScrollSliderImageStretch[2].setX(pushStretch->left); m_hScrollSliderImageStretch[2].setY(pushStretch->top); m_hScrollSliderImageStretch[2].setWidth(pushStretch->right - pushStretch->left); m_hScrollSliderImageStretch[2].setHeight(pushStretch->bottom - pushStretch->top); } } else { delete img; } } return HGBASE_ERR_OK; } HGResult HGImgThumb::setVScrollImage(const QImage *image, const HGRect *stretch) { if (MouseStatus_Null != m_mousePressStatus || 0 != m_operate || m_draging || m_frameSelection) { return HGBASE_ERR_FAIL; } if (0 != m_frontItems.size()) { return HGBASE_ERR_FAIL; } if (nullptr == image) { delete m_vScrollImage; m_vScrollImage = nullptr; } else { QImage *img = new QImage(*image); if (!img->isNull()) { if (nullptr != m_vScrollImage) delete m_vScrollImage; m_vScrollImage = img; if (nullptr == stretch || stretch->left < 0 || stretch->top < 0 || stretch->right > m_vScrollImage->width() || stretch->bottom > m_vScrollImage->height() || stretch->left >= stretch->right || stretch->top >= stretch->bottom) { m_vScrollImageStretch.setX(0); m_vScrollImageStretch.setY(0); m_vScrollImageStretch.setWidth(m_vScrollImage->width()); m_vScrollImageStretch.setHeight(m_vScrollImage->height()); } else { m_vScrollImageStretch.setX(stretch->left); m_vScrollImageStretch.setY(stretch->top); m_vScrollImageStretch.setWidth(stretch->right - stretch->left); m_vScrollImageStretch.setHeight(stretch->bottom - stretch->top); } } else { delete img; } } return HGBASE_ERR_OK; } HGResult HGImgThumb::setVScrollSliderImage(const QImage *normalImage, const HGRect *normalStretch, const QImage *hotImage, const HGRect *hotStretch, const QImage *pushImage, const HGRect *pushStretch) { if (MouseStatus_Null != m_mousePressStatus || 0 != m_operate || m_draging || m_frameSelection) { return HGBASE_ERR_FAIL; } if (0 != m_frontItems.size()) { return HGBASE_ERR_FAIL; } if (nullptr == normalImage) { delete m_vScrollSliderImage[0]; m_vScrollSliderImage[0] = nullptr; } else { QImage *img = new QImage(*normalImage); if (!img->isNull()) { if (nullptr != m_vScrollSliderImage[0]) delete m_vScrollSliderImage[0]; m_vScrollSliderImage[0] = img; if (nullptr == normalStretch || normalStretch->left < 0 || normalStretch->top < 0 || normalStretch->right > m_vScrollSliderImage[0]->width() || normalStretch->bottom > m_vScrollSliderImage[0]->height() || normalStretch->left >= normalStretch->right || normalStretch->top >= normalStretch->bottom) { m_vScrollSliderImageStretch[0].setX(0); m_vScrollSliderImageStretch[0].setY(0); m_vScrollSliderImageStretch[0].setWidth(m_vScrollSliderImage[0]->width()); m_vScrollSliderImageStretch[0].setHeight(m_vScrollSliderImage[0]->height()); } else { m_vScrollSliderImageStretch[0].setX(normalStretch->left); m_vScrollSliderImageStretch[0].setY(normalStretch->top); m_vScrollSliderImageStretch[0].setWidth(normalStretch->right - normalStretch->left); m_vScrollSliderImageStretch[0].setHeight(normalStretch->bottom - normalStretch->top); } } else { delete img; } } if (nullptr == hotImage) { delete m_vScrollSliderImage[1]; m_vScrollSliderImage[1] = nullptr; } else { QImage *img = new QImage(*hotImage); if (!img->isNull()) { if (nullptr != m_vScrollSliderImage[1]) delete m_vScrollSliderImage[1]; m_vScrollSliderImage[1] = img; if (nullptr == hotStretch || hotStretch->left < 0 || hotStretch->top < 0 || hotStretch->right > m_vScrollSliderImage[1]->width() || hotStretch->bottom > m_vScrollSliderImage[1]->height() || hotStretch->left >= hotStretch->right || hotStretch->top >= hotStretch->bottom) { m_vScrollSliderImageStretch[1].setX(0); m_vScrollSliderImageStretch[1].setY(0); m_vScrollSliderImageStretch[1].setWidth(m_vScrollSliderImage[1]->width()); m_vScrollSliderImageStretch[1].setHeight(m_vScrollSliderImage[1]->height()); } else { m_vScrollSliderImageStretch[1].setX(hotStretch->left); m_vScrollSliderImageStretch[1].setY(hotStretch->top); m_vScrollSliderImageStretch[1].setWidth(hotStretch->right - hotStretch->left); m_vScrollSliderImageStretch[1].setHeight(hotStretch->bottom - hotStretch->top); } } else { delete img; } } if (nullptr == pushImage) { delete m_vScrollSliderImage[2]; m_vScrollSliderImage[2] = nullptr; } else { QImage *img = new QImage(*pushImage); if (!img->isNull()) { if (nullptr != m_vScrollSliderImage[2]) delete m_vScrollSliderImage[2]; m_vScrollSliderImage[2] = img; if (nullptr == pushStretch || pushStretch->left < 0 || pushStretch->top < 0 || pushStretch->right > m_vScrollSliderImage[2]->width() || pushStretch->bottom > m_vScrollSliderImage[2]->height() || pushStretch->left >= pushStretch->right || pushStretch->top >= hotStretch->bottom) { m_vScrollSliderImageStretch[2].setX(0); m_vScrollSliderImageStretch[2].setY(0); m_vScrollSliderImageStretch[2].setWidth(m_vScrollSliderImage[2]->width()); m_vScrollSliderImageStretch[2].setHeight(m_vScrollSliderImage[2]->height()); } else { m_vScrollSliderImageStretch[2].setX(pushStretch->left); m_vScrollSliderImageStretch[2].setY(pushStretch->top); m_vScrollSliderImageStretch[2].setWidth(pushStretch->right - pushStretch->left); m_vScrollSliderImageStretch[2].setHeight(pushStretch->bottom - pushStretch->top); } } else { delete img; } } return HGBASE_ERR_OK; } HGResult HGImgThumb::setNullScrollImage(const QImage *image) { if (MouseStatus_Null != m_mousePressStatus || 0 != m_operate || m_draging || m_frameSelection) { return HGBASE_ERR_FAIL; } if (0 != m_frontItems.size()) { return HGBASE_ERR_FAIL; } if (nullptr == image) { delete m_nullScrollImage; m_nullScrollImage = nullptr; } else { QImage *img = new QImage(*image); if (!img->isNull()) { if (nullptr != m_nullScrollImage) delete m_nullScrollImage; m_nullScrollImage = img; } else { delete img; } } return HGBASE_ERR_OK; } HGResult HGImgThumb::setType(ThumbType type) { if (MouseStatus_Null != m_mousePressStatus || 0 != m_operate || m_draging || m_frameSelection) { return HGBASE_ERR_FAIL; } if (m_type == type) { return HGBASE_ERR_OK; } m_type = type; int showWidth = 0, showHeight = 0; calcShowSize(this->width(), this->height(), m_gapSize, m_scrollSize, m_itemSize, m_itemTextHeight, m_type, (int)m_frontItems.size(), showWidth, showHeight, m_hScroll, m_vScroll); m_showThumb = false; memset(&m_thumbRect, 0, sizeof(ThumbRect)); if (showWidth > 0 && showHeight > 0) { m_showThumb = true; m_thumbRect.left = 0; m_thumbRect.top = 0; m_thumbRect.right = (double)showWidth; m_thumbRect.bottom = (double)showHeight; recalcShowRect(this->width(), this->height(), m_scrollSize, m_type, m_hScroll, m_vScroll, m_showThumb, m_thumbRect); } m_hotItemIndex = getItemIndex(mapFromGlobal(QCursor::pos()), m_mouseMoveStatus); Show(); return HGBASE_ERR_OK; } HGResult HGImgThumb::zoomIn() { if (MouseStatus_Null != m_mousePressStatus || 0 != m_operate || m_draging || m_frameSelection) { return HGBASE_ERR_FAIL; } if (0 == m_frontItems.size()) { return HGBASE_ERR_FAIL; } assert(m_showThumb); int itemSize = (int)((float)m_itemSize * 1.2f); int newItemSize = HGMIN(240, HGMAX(60, itemSize)); if (m_itemSize == newItemSize) { return HGBASE_ERR_FAIL; } HGBase_EnterLock(m_lockItemSize); m_itemSize = newItemSize; HGBase_LeaveLock(m_lockItemSize); if (nullptr != m_defItemImage) { assert(nullptr != m_itemImage); delete m_itemImage; m_itemImage = createItemImage(m_defItemImage, m_itemSize); assert(nullptr != m_itemImage); } int showWidth = 0, showHeight = 0; calcShowSize(this->width(), this->height(), m_gapSize, m_scrollSize, m_itemSize, m_itemTextHeight, m_type, (int)m_frontItems.size(), showWidth, showHeight, m_hScroll, m_vScroll); assert(showWidth > 0 && showHeight > 0); m_thumbRect.right = m_thumbRect.left + (double)showWidth; m_thumbRect.bottom = m_thumbRect.top + (double)showHeight; recalcShowRect(this->width(), this->height(), m_scrollSize, m_type, m_hScroll, m_vScroll, m_showThumb, m_thumbRect); m_hotItemIndex = getItemIndex(mapFromGlobal(QCursor::pos()), m_mouseMoveStatus); Show(); HGBase_EnterLock(m_lockBack); m_backList.clear(); for (int i = 0; i < (int)m_frontItems.size(); ++i) { m_backList.push_back(m_frontItems[i]->fileName); } HGBase_LeaveLock(m_lockBack); HGBase_SetEvent(m_event); return HGBASE_ERR_OK; } HGResult HGImgThumb::zoomOut() { if (MouseStatus_Null != m_mousePressStatus || 0 != m_operate || m_draging || m_frameSelection) { return HGBASE_ERR_FAIL; } if (0 == m_frontItems.size()) { return HGBASE_ERR_FAIL; } assert(m_showThumb); int itemSize = (int)((float)m_itemSize * 1.0f / 1.2f); int newItemSize = HGMIN(240, HGMAX(60, itemSize)); if (m_itemSize == newItemSize) { return HGBASE_ERR_FAIL; } HGBase_EnterLock(m_lockItemSize); m_itemSize = newItemSize; HGBase_LeaveLock(m_lockItemSize); if (nullptr != m_defItemImage) { assert(nullptr != m_itemImage); delete m_itemImage; m_itemImage = createItemImage(m_defItemImage, m_itemSize); assert(nullptr != m_itemImage); } int showWidth = 0, showHeight = 0; calcShowSize(this->width(), this->height(), m_gapSize, m_scrollSize, m_itemSize, m_itemTextHeight, m_type, (int)m_frontItems.size(), showWidth, showHeight, m_hScroll, m_vScroll); assert(showWidth > 0 && showHeight > 0); m_thumbRect.right = m_thumbRect.left + (double)showWidth; m_thumbRect.bottom = m_thumbRect.top + (double)showHeight; recalcShowRect(this->width(), this->height(), m_scrollSize, m_type, m_hScroll, m_vScroll, m_showThumb, m_thumbRect); m_hotItemIndex = getItemIndex(mapFromGlobal(QCursor::pos()), m_mouseMoveStatus); Show(); HGBase_EnterLock(m_lockBack); m_backList.clear(); for (int i = 0; i < (int)m_frontItems.size(); ++i) { m_backList.push_back(m_frontItems[i]->fileName); } HGBase_LeaveLock(m_lockBack); HGBase_SetEvent(m_event); return HGBASE_ERR_OK; } HGResult HGImgThumb::getItemCount(int *count) { if (nullptr == count) { return HGBASE_ERR_INVALIDARG; } *count = (int)m_frontItems.size(); return HGBASE_ERR_OK; } HGResult HGImgThumb::addItem(const QString &fileName) { QStringList fileNames; fileNames.append(fileName); return addItems(fileNames); } HGResult HGImgThumb::addItems(const QStringList &fileNames) { return insertItems(fileNames, (int)m_frontItems.size(), true); } HGResult HGImgThumb::insertItem(const QString &fileName, int pos) { QStringList fileNames; fileNames.append(fileName); return insertItems(fileNames, pos); } HGResult HGImgThumb::insertItems(const QStringList &fileNames, int pos, bool append) { if (pos < 0 || pos > (int)m_frontItems.size()) { return HGBASE_ERR_INVALIDARG; } bool findInThumb = false; std::vector stdFileNames; for (int i = 0; i < (int)fileNames.size(); ++i) { QString stdFileName = getStdFileName(fileNames[i]); QFileInfo fileInfo(stdFileName); if (!fileInfo.isFile()) { continue; } bool find = false; for (int j = 0; j < (int)stdFileNames.size(); ++j) { if (stdFileNames[j] == stdFileName) { find = true; break; } } if (!find) { HGUInt fmtType = 0; HGImgFmt_GetImgFmtTypeFromFileName(getStdString(stdFileName).c_str(), &fmtType); if (0 != fmtType) { if (!findInThumb) { for (int i = 0; i < (int)m_frontItems.size(); ++i) { if (m_frontItems[i]->fileName == stdFileName) { findInThumb = true; break; } } } stdFileNames.push_back(stdFileName); } } } if (stdFileNames.empty()) { if (!fileNames.empty()) { QMessageBox::information(this, tr("tips"), tr("unsupported file format")); } return HGBASE_ERR_INVALIDARG; } bool isMove = false; if (findInThumb) { if (1 == stdFileNames.size()) { int index = findIndex(stdFileNames[0]); assert(-1 != index); if (pos == index || pos == index + 1) { QMessageBox::information(this, tr("tips"), tr("file have been loaded")); } else { QString info = append ? tr("file have been loaded, do you want to move to end?") : tr("file have been loaded, do you want to move to specified location?"); QMessageBox msg(QMessageBox::Question, tr("Question"), info, QMessageBox::Yes | QMessageBox::No, this); msg.setButtonText(QMessageBox::Yes, tr("yes")); msg.setButtonText(QMessageBox::No, tr("no")); msg.exec(); if (msg.clickedButton() == msg.button(QMessageBox::Yes)) { isMove = true; } } } else { QString info = append ? tr("some files have been loaded, do you want to move to end?") : tr("some files have been loaded, do you want to move to specified location?"); QMessageBox msg(QMessageBox::Question, tr("Question"), info, QMessageBox::Yes | QMessageBox::No, this); msg.setButtonText(QMessageBox::Yes, tr("yes")); msg.setButtonText(QMessageBox::No, tr("no")); msg.exec(); if (msg.clickedButton() == msg.button(QMessageBox::Yes)) { isMove = true; } } } reset(); int oldItemCount = (int)m_frontItems.size(); int oldCurrItemIndex = m_curItemIndex; QString oldCurrItemFilePath; if (-1 != oldCurrItemIndex) oldCurrItemFilePath = m_frontItems[oldCurrItemIndex]->fileName; std::vector oldSelectedIndexs; for (int i = 0; i < (int)m_frontItems.size(); ++i) { if (m_frontItems[i]->selected) oldSelectedIndexs.push_back(i); m_frontItems[i]->selected = false; } int posEx = pos; for (int i = 0; i < (int)stdFileNames.size(); ++i) { const QString &stdFileName = stdFileNames[i]; int oldIndex = findIndex(stdFileName); if (-1 == oldIndex) { HGImgThumbItem *item = new HGImgThumbItem; item->fileName = stdFileName; item->selected = true; HGBase_EnterLock(m_lockFront); item->selected = true; if (posEx != (int)m_frontItems.size()) m_frontItems.insert(m_frontItems.begin() + posEx, item); else m_frontItems.push_back(item); HGBase_LeaveLock(m_lockFront); HGBase_EnterLock(m_lockBack); m_backList.push_back(stdFileName); HGBase_LeaveLock(m_lockBack); HGBase_SetEvent(m_event); ++posEx; } else { if (isMove) { HGImgThumbItem *item = m_frontItems[oldIndex]; item->selected = true; if (oldIndex < posEx) { if (pos == posEx) { --pos; } --posEx; } HGBase_EnterLock(m_lockFront); m_frontItems.erase(m_frontItems.begin() + oldIndex); if (posEx != (int)m_frontItems.size()) m_frontItems.insert(m_frontItems.begin() + posEx, item); else m_frontItems.push_back(item); HGBase_LeaveLock(m_lockFront); ++posEx; } else { m_frontItems[oldIndex]->selected = true; m_curItemIndex = oldIndex; m_signItemIndex = oldIndex; locateItem(oldIndex); recalcShowRect(this->width(), this->height(), m_scrollSize, m_type, m_hScroll, m_vScroll, m_showThumb, m_thumbRect); } } } if (pos != posEx) { m_curItemIndex = posEx - 1; m_signItemIndex = posEx - 1; int showWidth = 0, showHeight = 0; calcShowSize(this->width(), this->height(), m_gapSize, m_scrollSize, m_itemSize, m_itemTextHeight, m_type, (int)m_frontItems.size(), showWidth, showHeight, m_hScroll, m_vScroll); assert(showWidth > 0 && showHeight > 0); m_showThumb = true; m_thumbRect.right = m_thumbRect.left + (double)showWidth; m_thumbRect.bottom = m_thumbRect.top + (double)showHeight; locateItem(posEx - 1); recalcShowRect(this->width(), this->height(), m_scrollSize, m_type, m_hScroll, m_vScroll, m_showThumb, m_thumbRect); } m_hotItemIndex = getItemIndex(mapFromGlobal(QCursor::pos()), m_mouseMoveStatus); Show(); int newItemCount = (int)m_frontItems.size(); int newCurrItemIndex = m_curItemIndex; QString newCurrItemFilePath; if (-1 != newCurrItemIndex) newCurrItemFilePath = m_frontItems[newCurrItemIndex]->fileName; std::vector newSelectedIndexs; for (int i = 0; i < (int)m_frontItems.size(); ++i) { if (m_frontItems[i]->selected) newSelectedIndexs.push_back(i); } if (newItemCount != oldItemCount) emit itemCountChanged((int)m_frontItems.size()); if (newCurrItemIndex != oldCurrItemIndex || newCurrItemFilePath != oldCurrItemFilePath) emit currItemChanged(m_curItemIndex); if (newSelectedIndexs != oldSelectedIndexs) emit itemSelectingChanged(); return HGBASE_ERR_OK; } HGResult HGImgThumb::moveItems(const QStringList &fileNames, int pos) { if (pos < 0 || pos > (int)m_frontItems.size()) { return HGBASE_ERR_INVALIDARG; } std::vector stdFileNames; for (int i = 0; i < (int)fileNames.size(); ++i) { QString stdFileName = getStdFileName(fileNames[i]); int oldIndex = findIndex(stdFileName); if (-1 == oldIndex) { continue; } bool find = false; for (int j = 0; j < (int)stdFileNames.size(); ++j) { if (stdFileNames[j] == stdFileName) { find = true; break; } } if (!find) { stdFileNames.push_back(stdFileName); } } if (stdFileNames.empty()) { return HGBASE_ERR_INVALIDARG; } reset(); QString curItemFilePath; if (-1 != m_curItemIndex) curItemFilePath = m_frontItems[m_curItemIndex]->fileName; QString signItemFilePath; if (-1 != m_signItemIndex) signItemFilePath = m_frontItems[m_signItemIndex]->fileName; int oldCurItemIndex = m_curItemIndex; std::vector oldSelectedIndexs; for (int i = 0; i < (int)m_frontItems.size(); ++i) { if (m_frontItems[i]->selected) oldSelectedIndexs.push_back(i); } int posEx = pos; for (int i = 0; i < (int)stdFileNames.size(); ++i) { const QString &stdFileName = stdFileNames[i]; int oldIndex = findIndex(stdFileName); assert(-1 != oldIndex); HGImgThumbItem *item = m_frontItems[oldIndex]; if (oldIndex < posEx) --posEx; HGBase_EnterLock(m_lockFront); m_frontItems.erase(m_frontItems.begin() + oldIndex); if (posEx != (int)m_frontItems.size()) m_frontItems.insert(m_frontItems.begin() + posEx, item); else m_frontItems.push_back(item); HGBase_LeaveLock(m_lockFront); ++posEx; } m_curItemIndex = findIndex(curItemFilePath); m_signItemIndex = findIndex(signItemFilePath); if (-1 != m_curItemIndex) { locateItem(m_curItemIndex); recalcShowRect(this->width(), this->height(), m_scrollSize, m_type, m_hScroll, m_vScroll, m_showThumb, m_thumbRect); } m_hotItemIndex = getItemIndex(mapFromGlobal(QCursor::pos()), m_mouseMoveStatus); Show(); std::vector newSelectedIndexs; for (int i = 0; i < (int)m_frontItems.size(); ++i) { if (m_frontItems[i]->selected) newSelectedIndexs.push_back(i); } if (m_curItemIndex != oldCurItemIndex) emit currItemChanged(m_curItemIndex); if (newSelectedIndexs != oldSelectedIndexs) emit itemSelectingChanged(); return HGBASE_ERR_OK; } HGResult HGImgThumb::moveItemsTo(const QStringList &fileNames, int index) { if (index < 0 || index >= (int)m_frontItems.size()) { return HGBASE_ERR_INVALIDARG; } std::vector stdFileNames; for (int i = 0; i < (int)fileNames.size(); ++i) { QString stdFileName = getStdFileName(fileNames[i]); int oldIndex = findIndex(stdFileName); if (-1 == oldIndex) { continue; } bool find = false; for (int j = 0; j < (int)stdFileNames.size(); ++j) { if (stdFileNames[j] == stdFileName) { find = true; break; } } if (!find) { stdFileNames.push_back(stdFileName); } } if (stdFileNames.empty()) { return HGBASE_ERR_INVALIDARG; } reset(); QString curItemFilePath; if (-1 != m_curItemIndex) curItemFilePath = m_frontItems[m_curItemIndex]->fileName; QString signItemFilePath; if (-1 != m_signItemIndex) signItemFilePath = m_frontItems[m_signItemIndex]->fileName; int oldCurItemIndex = m_curItemIndex; std::vector oldSelectedIndexs; for (int i = 0; i < (int)m_frontItems.size(); ++i) { if (m_frontItems[i]->selected) oldSelectedIndexs.push_back(i); } HGBase_EnterLock(m_lockFront); std::vector items; for (int i = 0; i < (int)stdFileNames.size(); ++i) { const QString &stdFileName = stdFileNames[i]; int oldIndex = findIndex(stdFileName); assert(-1 != oldIndex); HGImgThumbItem *item = m_frontItems[oldIndex]; m_frontItems.erase(m_frontItems.begin() + oldIndex); items.push_back(item); } if (index < (int)m_frontItems.size()) { int indexEx = index; for (int i = 0; i < (int)items.size(); ++i) { m_frontItems.insert(m_frontItems.begin() + indexEx, items[i]); ++indexEx; } } else { for (int i = 0; i < (int)items.size(); ++i) { m_frontItems.push_back(items[i]); } } HGBase_LeaveLock(m_lockFront); m_curItemIndex = findIndex(curItemFilePath); m_signItemIndex = findIndex(signItemFilePath); locateItem(index); recalcShowRect(this->width(), this->height(), m_scrollSize, m_type, m_hScroll, m_vScroll, m_showThumb, m_thumbRect); m_hotItemIndex = getItemIndex(mapFromGlobal(QCursor::pos()), m_mouseMoveStatus); Show(); std::vector newSelectedIndexs; for (int i = 0; i < (int)m_frontItems.size(); ++i) { if (m_frontItems[i]->selected) newSelectedIndexs.push_back(i); } if (m_curItemIndex != oldCurItemIndex) emit currItemChanged(m_curItemIndex); if (newSelectedIndexs != oldSelectedIndexs) emit itemSelectingChanged(); return HGBASE_ERR_OK; } HGResult HGImgThumb::getItemFileName(int index, QString &fileName) { if (index < 0 || index >= (int)m_frontItems.size()) { return HGBASE_ERR_INVALIDARG; } fileName = m_frontItems[index]->fileName; return HGBASE_ERR_OK; } HGResult HGImgThumb::getCurrItem(int *index) { if (nullptr == index) { return HGBASE_ERR_INVALIDARG; } *index = m_curItemIndex; return HGBASE_ERR_OK; } HGResult HGImgThumb::setCurrItem(int index) { if (MouseStatus_Null != m_mousePressStatus || 0 != m_operate || m_draging || m_frameSelection) { return HGBASE_ERR_FAIL; } if (index < 0 || index >= (int)m_frontItems.size()) { return HGBASE_ERR_INVALIDARG; } bool emitCurrItemChanged = false; bool emitSelectingChanged = false; if (m_curItemIndex != index) { emitCurrItemChanged = true; m_curItemIndex = index; } m_signItemIndex = index; for (int i = 0; i < (int)m_frontItems.size(); ++i) { if (i == index) { if (!m_frontItems[i]->selected) emitSelectingChanged = true; m_frontItems[i]->selected = true; } else { if (m_frontItems[i]->selected) emitSelectingChanged = true; m_frontItems[i]->selected = false; } } locateItem(index); recalcShowRect(this->width(), this->height(), m_scrollSize, m_type, m_hScroll, m_vScroll, m_showThumb, m_thumbRect); m_hotItemIndex = getItemIndex(mapFromGlobal(QCursor::pos()), m_mouseMoveStatus); Show(); if (emitCurrItemChanged) emit currItemChanged(m_curItemIndex); if (emitSelectingChanged) emit itemSelectingChanged(); return HGBASE_ERR_OK; } HGResult HGImgThumb::resetCurrItem() { if (MouseStatus_Null != m_mousePressStatus || 0 != m_operate || m_draging || m_frameSelection) { return HGBASE_ERR_FAIL; } bool emitCurrItemChanged = false; bool emitSelectingChanged = false; if (m_curItemIndex != -1) { emitCurrItemChanged = true; m_curItemIndex = -1; } for (int i = 0; i < (int)m_frontItems.size(); ++i) { if (m_frontItems[i]->selected) emitSelectingChanged = true; m_frontItems[i]->selected = false; } Show(); if (emitCurrItemChanged) emit currItemChanged(m_curItemIndex); if (emitSelectingChanged) emit itemSelectingChanged(); return HGBASE_ERR_OK; } HGResult HGImgThumb::removeItem(int index, ThumbRemoveFlag flag) { std::vector indexs; indexs.push_back(index); return removeItems(indexs, flag); } HGResult HGImgThumb::removeItems(const std::vector &indexs, ThumbRemoveFlag flag) { if (MouseStatus_Null != m_mousePressStatus || 0 != m_operate || m_draging || m_frameSelection) { return HGBASE_ERR_FAIL; } std::vector indexs2; for (int i = 0; i < (int)indexs.size(); ++i) { if (indexs[i] < 0 || indexs[i] >= (int)m_frontItems.size()) { return HGBASE_ERR_INVALIDARG; } bool find = false; for (int j = 0; j < (int)indexs2.size(); ++j) { if (indexs2[j] == indexs[i]) { find = true; break; } } if (!find) { indexs2.push_back(indexs[i]); } } if (indexs2.empty()) { return HGBASE_ERR_INVALIDARG; } bool emitItemSelectingChange = false; bool emitCurrItemChange = false; for (int i = 0; i < (int)indexs2.size(); ++i) { int index = indexs2[i]; if (m_frontItems[index]->selected) emitItemSelectingChange = true; HGBase_EnterLock(m_lockBack); std::list::iterator iter; for (iter = m_backList.begin(); iter != m_backList.end(); ++iter) { if (0 == (*iter).compare(m_frontItems[index]->fileName)) { m_backList.erase(iter); break; } } HGBase_LeaveLock(m_lockBack); if (flag == ThumbRemoveFlag_AllowUndo) ; else if (flag == ThumbRemoveFlag_Delete) QFile::remove(m_frontItems[index]->fileName); HGBase_EnterLock(m_lockFront); delete m_frontItems[index]; m_frontItems.erase(m_frontItems.begin() + index); HGBase_LeaveLock(m_lockFront); if (m_curItemIndex == index) { m_curItemIndex = -1; emitCurrItemChange = true; } else if (m_curItemIndex > index) { --m_curItemIndex; emitCurrItemChange = true; } if (m_signItemIndex == index) m_signItemIndex = -1; else if (m_signItemIndex > index) --m_signItemIndex; for (int j = i + 1; j < (int)indexs2.size(); ++j) { if (indexs2[j] > index) { --indexs2[j]; } } } int showWidth = 0, showHeight = 0; calcShowSize(this->width(), this->height(), m_gapSize, m_scrollSize, m_itemSize, m_itemTextHeight, m_type, (int)m_frontItems.size(), showWidth, showHeight, m_hScroll, m_vScroll); if (showWidth <= 0 || showHeight <= 0) { m_showThumb = false; memset(&m_thumbRect, 0, sizeof(ThumbRect)); } else { m_thumbRect.right = m_thumbRect.left + (double)showWidth; m_thumbRect.bottom = m_thumbRect.top + (double)showHeight; recalcShowRect(this->width(), this->height(), m_scrollSize, m_type, m_hScroll, m_vScroll, m_showThumb, m_thumbRect); } m_hotItemIndex = getItemIndex(mapFromGlobal(QCursor::pos()), m_mouseMoveStatus); Show(); emit itemCountChanged((int)m_frontItems.size()); if (emitCurrItemChange) emit currItemChanged(m_curItemIndex); if (emitItemSelectingChange) emit itemSelectingChanged(); return HGBASE_ERR_OK; } HGResult HGImgThumb::removeAllItems(ThumbRemoveFlag flag) { if (m_frontItems.empty()) { return HGBASE_ERR_OK; } reset(); bool emitItemSelectingChange = false; HGBase_EnterLock(m_lockBack); m_backList.clear(); HGBase_LeaveLock(m_lockBack); while (!m_frontItems.empty()) { if (m_frontItems[0]->selected) emitItemSelectingChange = true; if (flag == ThumbRemoveFlag_AllowUndo) ; else if (flag == ThumbRemoveFlag_Delete) QFile::remove(m_frontItems[0]->fileName); HGBase_EnterLock(m_lockFront); delete m_frontItems[0]; m_frontItems.erase(m_frontItems.begin()); HGBase_LeaveLock(m_lockFront); } bool emitItemChange = false; if (-1 != m_curItemIndex) { m_curItemIndex = -1; emitItemChange = true; } m_signItemIndex = -1; m_hScroll = false; m_vScroll = false; m_showThumb = false; memset(&m_thumbRect, 0, sizeof(ThumbRect)); m_hotItemIndex = getItemIndex(mapFromGlobal(QCursor::pos()), m_mouseMoveStatus); Show(); emit itemCountChanged((int)m_frontItems.size()); if (emitItemChange) emit currItemChanged(m_curItemIndex); if (emitItemSelectingChange) emit itemSelectingChanged(); return HGBASE_ERR_OK; } HGResult HGImgThumb::bookSort() { if (MouseStatus_Null != m_mousePressStatus || 0 != m_operate || m_draging || m_frameSelection) { return HGBASE_ERR_FAIL; } int oldCurItemIndex = m_curItemIndex; for (int i = 0; i < (int)m_frontItems.size(); ++i) { if (m_curItemIndex == i) { if (0 == i % 2) m_curItemIndex = i / 2; else m_curItemIndex = (int)m_frontItems.size() - (i + 1) / 2; break; } } for (int i = 0; i < (int)m_frontItems.size(); ++i) { if (m_signItemIndex == i) { if (0 == i % 2) m_signItemIndex = i / 2; else m_signItemIndex = (int)m_frontItems.size() - (i + 1) / 2; break; } } std::list items1, items2; for (int i = 0; i < (int)m_frontItems.size(); ++i) { HGImgThumbItem *item = m_frontItems[i]; if (0 == i % 2) items1.push_back(item); else items2.push_front(item); } HGBase_EnterLock(m_lockFront); m_frontItems.clear(); std::list::const_iterator iter; for (iter = items1.begin(); iter != items1.end(); ++iter) m_frontItems.push_back(*iter); for (iter = items2.begin(); iter != items2.end(); ++iter) m_frontItems.push_back(*iter); HGBase_LeaveLock(m_lockFront); if (-1 != m_curItemIndex) { locateItem(m_curItemIndex); recalcShowRect(this->width(), this->height(), m_scrollSize, m_type, m_hScroll, m_vScroll, m_showThumb, m_thumbRect); } m_hotItemIndex = getItemIndex(mapFromGlobal(QCursor::pos()), m_mouseMoveStatus); Show(); if (oldCurItemIndex != m_curItemIndex) emit currItemChanged(m_curItemIndex); return HGBASE_ERR_OK; } HGResult HGImgThumb::selectItem(int index, bool select) { if (MouseStatus_Null != m_mousePressStatus || 0 != m_operate || m_draging || m_frameSelection) { return HGBASE_ERR_FAIL; } if (index < 0 || index >= (int)m_frontItems.size()) { return HGBASE_ERR_INVALIDARG; } if (m_frontItems[index]->selected == select) { return HGBASE_ERR_OK; } m_frontItems[index]->selected = select; Show(); emit itemSelectingChanged(); return HGBASE_ERR_OK; } HGResult HGImgThumb::itemIsSelect(int index, bool *select) { if (index < 0 || index >= (int)m_frontItems.size() || nullptr == select) { return HGBASE_ERR_INVALIDARG; } *select = m_frontItems[index]->selected; return HGBASE_ERR_OK; } HGResult HGImgThumb::updateItem(int index, const QString &fileName) { if (MouseStatus_Null != m_mousePressStatus || 0 != m_operate || m_draging || m_frameSelection) { return HGBASE_ERR_FAIL; } if (index < 0 || index >= (int)m_frontItems.size()) { return HGBASE_ERR_INVALIDARG; } QString stdFileName = getStdFileName(fileName); QFileInfo fileInfo(stdFileName); if (!fileInfo.isFile()) { return HGBASE_ERR_FAIL; } if (-1 != findIndex(stdFileName)) { return HGBASE_ERR_FAIL; } QString oldFileName = m_frontItems[index]->fileName; m_frontItems[index]->fileName = stdFileName; HGBase_EnterLock(m_lockBack); std::list::iterator iter; for (iter = m_backList.begin(); iter != m_backList.end(); ++iter) { if (0 == (*iter).compare(oldFileName)) { m_backList.erase(iter); break; } } m_backList.push_front(stdFileName); HGBase_LeaveLock(m_lockBack); HGBase_SetEvent(m_event); return HGBASE_ERR_OK; } HGResult HGImgThumb::refreshItem(int index) { if (MouseStatus_Null != m_mousePressStatus || 0 != m_operate || m_draging || m_frameSelection) { return HGBASE_ERR_FAIL; } if (index < 0 || index >= (int)m_frontItems.size()) { return HGBASE_ERR_INVALIDARG; } QString fileName = m_frontItems[index]->fileName; HGBase_EnterLock(m_lockBack); std::list::iterator iter; for (iter = m_backList.begin(); iter != m_backList.end(); ++iter) { if (0 == (*iter).compare(fileName)) { m_backList.erase(iter); break; } } m_backList.push_front(fileName); HGBase_LeaveLock(m_lockBack); HGBase_SetEvent(m_event); return HGBASE_ERR_OK; } HGResult HGImgThumb::refreshItem(const QString &fileName) { if (fileName.isEmpty()) { return HGBASE_ERR_INVALIDARG; } QString stdFileName = getStdFileName(fileName); int index = findIndex(fileName); return refreshItem(index); } HGResult HGImgThumb::refreshAllItems() { if (MouseStatus_Null != m_mousePressStatus || 0 != m_operate || m_draging || m_frameSelection) { return HGBASE_ERR_FAIL; } HGBase_EnterLock(m_lockBack); m_backList.clear(); for (int i = 0; i < (int)m_frontItems.size(); ++i) { m_backList.push_back(m_frontItems[i]->fileName); } HGBase_LeaveLock(m_lockBack); HGBase_SetEvent(m_event); return HGBASE_ERR_OK; } void HGImgThumb::notify_mouse_leave(void) { leaveEvent(nullptr); } void HGImgThumb::mousePressEvent(QMouseEvent *e) { m_mouseOn = true; MouseStatus mouseStatus = MouseStatus_Null; int index = getItemIndex(e->pos(), mouseStatus); if (-1 == index && MouseStatus_Null != mouseStatus) { // 右键不处理滚动条区域 if (e->button() == Qt::LeftButton) { m_mousePressStatus = mouseStatus; m_mousePressBeginX = e->pos().x(); m_mousePressBeginY = e->pos().y(); Show(); } return; } m_hitMouseButtons = e->button(); m_hitKeyboardModifiers = QGuiApplication::keyboardModifiers(); m_hitItemIndex = index; bool emitCurItemChange = false; bool emitItemSelectingChange = false; if (e->button() == Qt::RightButton) // 右键按下 { if (-1 != index) { if (Qt::ControlModifier != m_hitKeyboardModifiers) { if (!m_frontItems[index]->selected) { for (int i = 0; i < (int)m_frontItems.size(); ++i) { m_frontItems[i]->selected = (i == index) ? true : false; } emitItemSelectingChange = true; } if (index != m_curItemIndex) { m_curItemIndex = index; emitCurItemChange = true; } m_pushItemIndex = index; m_signItemIndex = index; } } } else // 左键按下 { if (QGuiApplication::keyboardModifiers() == Qt::ControlModifier) { if (-1 != index) { if (index != m_curItemIndex) { m_curItemIndex = index; emitCurItemChange = true; } m_pushItemIndex = index; m_signItemIndex = index; } } else if (QGuiApplication::keyboardModifiers() == Qt::ShiftModifier) { if (-1 != index) { if (-1 == m_signItemIndex) { for (int i = 0; i < (int)m_frontItems.size(); ++i) { if (i == index) { if (!m_frontItems[i]->selected) emitItemSelectingChange = true; m_frontItems[i]->selected = true; } else { if (m_frontItems[i]->selected) emitItemSelectingChange = true; m_frontItems[i]->selected = false; } } } else { for (int i = 0; i < (int)m_frontItems.size(); ++i) { if (i >= HGMIN(index, m_signItemIndex) && i <= HGMAX(index, m_signItemIndex)) { if (!m_frontItems[i]->selected) emitItemSelectingChange = true; m_frontItems[i]->selected = true; } else { if (m_frontItems[i]->selected) emitItemSelectingChange = true; m_frontItems[i]->selected = false; } } } if (index != m_curItemIndex) { m_curItemIndex = index; emitCurItemChange = true; } m_pushItemIndex = index; } } else { if (-1 != index) { if (!m_frontItems[index]->selected) { for (int i = 0; i < (int)m_frontItems.size(); ++i) { m_frontItems[i]->selected = (i == index) ? true : false; } emitItemSelectingChange = true; } if (index != m_curItemIndex) { m_curItemIndex = index; emitCurItemChange = true; } m_pushItemIndex = index; m_signItemIndex = index; } } } if (-1 != index) { if (e->button() == Qt::LeftButton && index == m_curItemIndex) { // 准备拖动 m_operate = 1; m_operateStartX = e->pos().x(); m_operateStartY = e->pos().y(); } locateItem(index); recalcShowRect(this->width(), this->height(), m_scrollSize, m_type, m_hScroll, m_vScroll, m_showThumb, m_thumbRect); m_hotItemIndex = getItemIndex(mapFromGlobal(QCursor::pos()), m_mouseMoveStatus); } else { if (e->button() == Qt::LeftButton && 0 != (int)m_frontItems.size()) { assert(m_showThumb); // 准备框选 m_operate = 2; m_operateStartX = e->pos().x(); m_operateStartY = e->pos().y(); } } Show(); if (emitCurItemChange) emit currItemChanged(m_curItemIndex); if (emitItemSelectingChange) emit itemSelectingChanged(); } void HGImgThumb::mouseMoveEvent(QMouseEvent* e) { bool emitCurItemChange = false; bool emitItemSelectingChange = false; // 处理拖动 if (m_frameSelection) { m_frameSelectionRect.left = HGMIN(m_frameSelectionStartX, e->pos().x() - round(m_thumbRect.left)); m_frameSelectionRect.top = HGMIN(m_frameSelectionStartY, e->pos().y() - round(m_thumbRect.top)); m_frameSelectionRect.right = HGMAX(m_frameSelectionStartX, e->pos().x() - round(m_thumbRect.left)); m_frameSelectionRect.bottom = HGMAX(m_frameSelectionStartY, e->pos().y() - round(m_thumbRect.top)); m_frameSelectionRectValid = true; QRect rect1(m_frameSelectionRect.left, m_frameSelectionRect.top, m_frameSelectionRect.right - m_frameSelectionRect.left, m_frameSelectionRect.bottom - m_frameSelectionRect.top); for (int i = 0; i < (int)m_frontItems.size(); ++i) { QPoint pt = getItemPos(i); QRect rect2(pt.x(), pt.y(), m_itemSize, m_itemSize + m_itemTextHeight); if (rect1.intersects(rect2)) { if (!m_frontItems[i]->selected) emitItemSelectingChange = true; m_frontItems[i]->selected = true; } else { if (m_frontItems[i]->selected) emitItemSelectingChange = true; m_frontItems[i]->selected = false; } } if (e->pos().x() < 0) { m_thumbRect.left += -e->pos().x(); m_thumbRect.right += -e->pos().x(); recalcShowRect(this->width(), this->height(), m_scrollSize, m_type, m_hScroll, m_vScroll, m_showThumb, m_thumbRect); } else if (e->pos().x() > this->width()) { m_thumbRect.left -= (e->pos().x() - this->width()); m_thumbRect.right -= (e->pos().x() - this->width()); recalcShowRect(this->width(), this->height(), m_scrollSize, m_type, m_hScroll, m_vScroll, m_showThumb, m_thumbRect); } if (e->pos().y() < 0) { m_thumbRect.top += -e->pos().y(); m_thumbRect.bottom += -e->pos().y(); recalcShowRect(this->width(), this->height(), m_scrollSize, m_type, m_hScroll, m_vScroll, m_showThumb, m_thumbRect); } else if (e->pos().y() > this->height()) { m_thumbRect.top -= (e->pos().y() - this->height()); m_thumbRect.bottom -= (e->pos().y() - this->height()); recalcShowRect(this->width(), this->height(), m_scrollSize, m_type, m_hScroll, m_vScroll, m_showThumb, m_thumbRect); } } // 处理滚动条 if (MouseStatus_HScrollSlider == m_mousePressStatus) { int lXAmount = e->pos().x() - m_mousePressBeginX; double offset; if (!m_vScroll) { int rollTotalLen = this->width() - 2 * m_scrollSize; int rollLeft = round((double)rollTotalLen * (-m_thumbRect.left) / (double)(m_thumbRect.right - m_thumbRect.left)); int rollRight = round((double)rollTotalLen * (-m_thumbRect.left + this->width()) / (double)(m_thumbRect.right - m_thumbRect.left)); int rollLen = rollRight - rollLeft; if (rollLen >= m_minScrollSliderSize) offset = lXAmount * (m_thumbRect.right - m_thumbRect.left) / rollTotalLen; else offset = lXAmount * (m_thumbRect.right - m_thumbRect.left - this->width()) / (rollTotalLen - m_minScrollSliderSize); } else { int rollTotalLen = this->width() - 3 * m_scrollSize; int rollLeft = round((double)rollTotalLen * (-m_thumbRect.left) / (double)(m_thumbRect.right - m_thumbRect.left)); int rollRight = round((double)rollTotalLen * (-m_thumbRect.left + this->width() - m_scrollSize) / (double)(m_thumbRect.right - m_thumbRect.left)); int rollLen = rollRight - rollLeft; if (rollLen >= m_minScrollSliderSize) offset = lXAmount * (m_thumbRect.right - m_thumbRect.left) / rollTotalLen; else offset = lXAmount * (m_thumbRect.right - m_thumbRect.left - this->width() + m_scrollSize) / (rollTotalLen - m_minScrollSliderSize); } m_thumbRect.left -= offset; m_thumbRect.right -= offset; recalcShowRect(this->width(), this->height(), m_scrollSize, m_type, m_hScroll, m_vScroll, m_showThumb, m_thumbRect); m_mousePressBeginX = e->pos().x(); m_mousePressBeginY = e->pos().y(); } else if (MouseStatus_VScrollSlider == m_mousePressStatus) { int lYAmount = e->pos().y() - m_mousePressBeginY; double offset; if (!m_hScroll) { int rollTotalLen = this->height() - 2 * m_scrollSize; int rollTop = round((double)rollTotalLen * (-m_thumbRect.top) / (double)(m_thumbRect.bottom - m_thumbRect.top)); int rollBottom = round((double)rollTotalLen * (-m_thumbRect.top + this->height()) / (double)(m_thumbRect.bottom - m_thumbRect.top)); int rollLen = rollBottom - rollTop; if (rollLen >= m_minScrollSliderSize) offset = lYAmount * (m_thumbRect.bottom - m_thumbRect.top) / rollTotalLen; else offset = lYAmount * (m_thumbRect.bottom - m_thumbRect.top - this->height()) / (rollTotalLen - m_minScrollSliderSize); } else { int rollTotalLen = this->height() - 3 * m_scrollSize; int rollTop = round((double)rollTotalLen * (-m_thumbRect.top) / (double)(m_thumbRect.bottom - m_thumbRect.top)); int rollBottom = round((double)rollTotalLen * (-m_thumbRect.top + this->height() - m_scrollSize) / (double)(m_thumbRect.bottom - m_thumbRect.top)); int rollLen = rollBottom - rollTop; if (rollLen >= m_minScrollSliderSize) offset = lYAmount * (m_thumbRect.bottom - m_thumbRect.top) / rollTotalLen; else offset = lYAmount * (m_thumbRect.bottom - m_thumbRect.top - this->height() + m_scrollSize) / (rollTotalLen - m_minScrollSliderSize); } m_thumbRect.top -= offset; m_thumbRect.bottom -= offset; recalcShowRect(this->width(), this->height(), m_scrollSize, m_type, m_hScroll, m_vScroll, m_showThumb, m_thumbRect); m_mousePressBeginX = e->pos().x(); m_mousePressBeginY = e->pos().y(); } if (0 == m_operate) { m_hotItemIndex = getItemIndex(e->pos(), m_mouseMoveStatus); } else if (1 == m_operate) { if ((e->buttons() & Qt::LeftButton) && (e->pos() - QPoint(m_operateStartX, m_operateStartY)).manhattanLength() >= QApplication::startDragDistance() && -1 != m_curItemIndex && m_frontItems[m_curItemIndex]->selected) { QList urls; for (int i = 0; i < (int)m_frontItems.size(); ++i) { if (m_frontItems[i]->selected) urls.append(QUrl::fromLocalFile(m_frontItems[i]->fileName)); } QDrag *drag = new QDrag(this); QMimeData *mimeData = new QMimeData; mimeData->setUrls(urls); drag->setMimeData(mimeData); QPixmap pixmap; HGBase_EnterLock(m_lockFront); QImage *img = m_frontItems[m_curItemIndex]->image; if (nullptr == img) img = m_itemImage; if (nullptr != img) pixmap = QPixmap::fromImage(*img); HGBase_LeaveLock(m_lockFront); if (!pixmap.isNull()) { QPainter painter(&pixmap); QRect textRect(0, 0, pixmap.width(), pixmap.height()); char chCount[12]; sprintf(chCount, "%d", urls.count()); QFont countFont("微软雅黑", pixmap.width() / 4); painter.setFont(countFont); QPen countPen(QColor(0, 0, 0, 200)); painter.setPen(countPen); painter.drawText(textRect, Qt::AlignHCenter | Qt::AlignVCenter, chCount); drag->setPixmap(pixmap); drag->setHotSpot(QPoint(pixmap.width() / 2, 4 * pixmap.height() / 5)); } m_pushItemIndex = -1; m_operate = 0; m_operateStartX = -1; m_operateStartY = -1; m_hitMouseButtons = Qt::NoButton; m_hitKeyboardModifiers = Qt::NoModifier; m_hitItemIndex = -1; // 开始拖动 drag->exec(Qt::CopyAction); } } else if (2 == m_operate) { if ((e->buttons() & Qt::LeftButton) && (e->pos() - QPoint(m_operateStartX, m_operateStartY)).manhattanLength() >= QApplication::startDragDistance()) { m_frameSelectionStartX = m_operateStartX - round(m_thumbRect.left); m_frameSelectionStartY = m_operateStartY - round(m_thumbRect.top); m_pushItemIndex = -1; m_operate = 0; m_operateStartX = -1; m_operateStartY = -1; m_hitMouseButtons = Qt::NoButton; m_hitKeyboardModifiers = Qt::NoModifier; m_hitItemIndex = -1; for (int i = 0; i < (int)m_frontItems.size(); ++i) { if (m_frontItems[i]->selected) emitItemSelectingChange = true; m_frontItems[i]->selected = false; } // 开始框选 m_frameSelection = true; m_frameSelectionRect.left = HGMIN(m_frameSelectionStartX, e->pos().x() - round(m_thumbRect.left)); m_frameSelectionRect.top = HGMIN(m_frameSelectionStartY, e->pos().y() - round(m_thumbRect.top)); m_frameSelectionRect.right = HGMAX(m_frameSelectionStartX, e->pos().x() - round(m_thumbRect.left)); m_frameSelectionRect.bottom = HGMAX(m_frameSelectionStartY, e->pos().y() - round(m_thumbRect.top)); m_frameSelectionRectValid = true; } } Show(); if (emitCurItemChange) emit currItemChanged(m_curItemIndex); if (emitItemSelectingChange) emit itemSelectingChanged(); } void HGImgThumb::mouseReleaseEvent(QMouseEvent *e) { Q_UNUSED(e); m_frameSelectionRectValid = false; m_frameSelection = false; m_curInsertPos = -1; m_insertPtValid = false; m_draging = false; m_pushItemIndex = -1; m_operateStartX = -1; m_operateStartY = -1; m_operate = 0; Qt::MouseButtons oldHitMouseButtons = m_hitMouseButtons; Qt::KeyboardModifiers oldHitKeyboardModifiers = m_hitKeyboardModifiers; int oldHitItemIndex = m_hitItemIndex; m_hitMouseButtons = Qt::NoButton; m_hitKeyboardModifiers = Qt::NoModifier; m_hitItemIndex = -1; MouseStatus oldMousePressStatus = m_mousePressStatus; m_mousePressStatus = MouseStatus_Null; m_mousePressBeginX = -1; m_mousePressBeginY = -1; bool emitItemSelectingChanged = false; bool emitCurrItemChanged = false; // 处理拖动 // 处理按item区域 if (oldHitMouseButtons == Qt::RightButton) { if (-1 == oldHitItemIndex) { if (oldHitKeyboardModifiers == Qt::NoModifier) { for (int i = 0; i < (int)m_frontItems.size(); ++i) { if (m_frontItems[i]->selected) emitItemSelectingChanged = true; m_frontItems[i]->selected = false; } } } } else if (oldHitMouseButtons == Qt::LeftButton) { if (oldHitKeyboardModifiers == Qt::ControlModifier) { if (-1 != oldHitItemIndex) { if (m_frontItems[oldHitItemIndex]->selected) { m_frontItems[oldHitItemIndex]->selected = false; } else { m_frontItems[oldHitItemIndex]->selected = true; } emitItemSelectingChanged = true; } } else if (oldHitKeyboardModifiers == Qt::ShiftModifier) { // 什么也不做 } else { if (-1 == oldHitItemIndex) { for (int i = 0; i < (int)m_frontItems.size(); ++i) { if (m_frontItems[i]->selected) emitItemSelectingChanged = true; m_frontItems[i]->selected = false; } } else { for (int i = 0; i < (int)m_frontItems.size(); ++i) { if (i != oldHitItemIndex) { if (m_frontItems[i]->selected) emitItemSelectingChanged = true; m_frontItems[i]->selected = false; } } } } } // 处理按滚动条区域 MouseStatus mouseMoveStatus = MouseStatus_Null; getItemIndex(e->pos(), mouseMoveStatus); if (MouseStatus_HScrollLeft == oldMousePressStatus && MouseStatus_HScrollLeft == mouseMoveStatus) { m_thumbRect.left += (double)m_itemSize / 2.0; m_thumbRect.right += (double)m_itemSize / 2.0; recalcShowRect(this->width(), this->height(), m_scrollSize, m_type, m_hScroll, m_vScroll, m_showThumb, m_thumbRect); } else if (MouseStatus_HScrollRight == oldMousePressStatus && MouseStatus_HScrollRight == mouseMoveStatus) { m_thumbRect.left -= (double)m_itemSize / 2.0; m_thumbRect.right -= (double)m_itemSize / 2.0; recalcShowRect(this->width(), this->height(), m_scrollSize, m_type, m_hScroll, m_vScroll, m_showThumb, m_thumbRect); } else if (MouseStatus_VScrollTop == oldMousePressStatus && MouseStatus_VScrollTop == mouseMoveStatus) { m_thumbRect.top += (double)m_itemSize / 2.0; m_thumbRect.bottom += (double)m_itemSize / 2.0; recalcShowRect(this->width(), this->height(), m_scrollSize, m_type, m_hScroll, m_vScroll, m_showThumb, m_thumbRect); } else if (MouseStatus_VScrollBottom == oldMousePressStatus && MouseStatus_VScrollBottom == mouseMoveStatus) { m_thumbRect.top -= (double)m_itemSize / 2.0; m_thumbRect.bottom -= (double)m_itemSize / 2.0; recalcShowRect(this->width(), this->height(), m_scrollSize, m_type, m_hScroll, m_vScroll, m_showThumb, m_thumbRect); } m_hotItemIndex = getItemIndex(mapFromGlobal(QCursor::pos()), m_mouseMoveStatus); Show(); if (emitCurrItemChanged) emit currItemChanged(m_curItemIndex); if (emitItemSelectingChanged) emit itemSelectingChanged(); } void HGImgThumb::enterEvent(QEvent *e) { Q_UNUSED(e); m_mouseOn = true; } void HGImgThumb::leaveEvent(QEvent *e) { Q_UNUSED(e); m_frameSelectionRectValid = false; m_frameSelection = false; // 拖动状态不能重置 //m_curInsertPos = -1; //m_insertPtValid = false; //m_draging = false; m_pushItemIndex = -1; m_operateStartX = -1; m_operateStartY = -1; m_operate = 0; m_hitMouseButtons = Qt::NoButton; m_hitKeyboardModifiers = Qt::NoModifier; m_hitItemIndex = -1; m_mousePressStatus = MouseStatus_Null; m_mousePressBeginX = -1; m_mousePressBeginY = -1; m_mouseOn = false; m_hotItemIndex = -1; m_mouseMoveStatus = MouseStatus_Null; Show(); } static void GetShowImageRect(const HGRect *pWnd, int nImgWidth, int nImgHeight, HGRect &rcShowImage) { int nWndWidth = pWnd->right - pWnd->left; int nWndHeight = pWnd->bottom - pWnd->top; int left, top, right, bottom; if (nImgWidth > nWndWidth || nImgHeight > nWndHeight) { if (nImgWidth * nWndHeight < nImgHeight * nWndWidth) { int width = nWndHeight * nImgWidth / nImgHeight; left = (pWnd->left + pWnd->right - width) / 2; right = (pWnd->left + pWnd->right + width) / 2; top = pWnd->top; bottom = pWnd->bottom; } else { int height = nWndWidth * nImgHeight / nImgWidth; left = pWnd->left; right = pWnd->right; top = (pWnd->top + pWnd->bottom - height) / 2; bottom = (pWnd->top + pWnd->bottom + height) / 2; } } else { left = (pWnd->left + pWnd->right - nImgWidth) / 2; right = (pWnd->left + pWnd->right + nImgWidth) / 2; top = (pWnd->top + pWnd->bottom - nImgHeight) / 2; bottom = (pWnd->top + pWnd->bottom + nImgHeight) / 2; } rcShowImage.left = left; rcShowImage.top = top; rcShowImage.right = right; rcShowImage.bottom = bottom; } void HGImgThumb::paintEvent(QPaintEvent* e) { Q_UNUSED(e); QPainter painter(this); QRect rcWnd(0, 0, this->width(), this->height()); painter.fillRect(rcWnd, qRgb(250, 250, 250)); for (int i = 0; i < (int)m_frontItems.size(); ++i) { QPoint pt(getItemPos(i).x() + round(m_thumbRect.left), getItemPos(i).y() + round(m_thumbRect.top)); QRect rcItem(pt.x(), pt.y(), m_itemSize, m_itemSize + m_itemTextHeight); if (!rcItem.intersects(rcWnd)) { continue; } // 绘制图像 HGBase_EnterLock(m_lockFront); int imgOriginWidth = m_frontItems[i]->width; int imgOriginHeight = m_frontItems[i]->height; QImage *img = m_frontItems[i]->image; if (nullptr == img && nullptr != m_itemImage) { assert(nullptr != m_defItemImage); imgOriginWidth = m_defItemImage->width(); imgOriginHeight = m_defItemImage->height(); img = m_itemImage; } if (nullptr != img) { HGRect rcShow; HGRect rcItemShow = {pt.x(), pt.y(), pt.x() + m_itemSize, pt.y() + m_itemSize}; GetShowImageRect(&rcItemShow, imgOriginWidth, imgOriginHeight, rcShow); QRect destRect(rcShow.left, rcShow.top, rcShow.right - rcShow.left, rcShow.bottom - rcShow.top); painter.drawImage(destRect, *img); } HGBase_LeaveLock(m_lockFront); // 绘制itemIndex HGChar itemIndex[10] = {0}; sprintf(itemIndex, "%d", i + 1); QRect itemIndexRect(pt.x(), pt.y(), m_itemSize, m_itemSize); QFont itemIndexFont("微软雅黑", m_itemSize / 4); painter.setFont(itemIndexFont); QPen itemIndexPen(QColor(0, 0, 0, 100)); painter.setPen(itemIndexPen); painter.drawText(itemIndexRect, Qt::AlignHCenter | Qt::AlignVCenter, itemIndex); // 绘制文件名 HGChar fileName[256] = {0}; HGBase_GetFileName(m_frontItems[i]->fileName.toStdString().c_str(), fileName, 256); QRect fileNameRect(pt.x(), pt.y() + m_itemSize, m_itemSize, m_itemTextHeight); QFont fileNameFont("微软雅黑", 8); painter.setFont(fileNameFont); QPen fileNamePen(QColor(0, 0, 0, 255)); painter.setPen(fileNamePen); painter.drawText(fileNameRect, Qt::AlignHCenter | Qt::AlignVCenter, fileName); if (m_frontItems[i]->selected) { painter.fillRect(pt.x(), pt.y(), m_itemSize, m_itemSize + m_itemTextHeight, QColor(0, 0, 0, 128)); } } if (-1 != m_hotItemIndex && !m_frontItems[m_hotItemIndex]->selected) { QPoint pt(getItemPos(m_hotItemIndex).x() + round(m_thumbRect.left), getItemPos(m_hotItemIndex).y() + round(m_thumbRect.top)); painter.fillRect(pt.x(), pt.y(), m_itemSize, m_itemSize + m_itemTextHeight, QColor(0, 0, 0, 64)); } if (-1 != m_pushItemIndex && !m_frontItems[m_pushItemIndex]->selected) { QPoint pt(getItemPos(m_pushItemIndex).x() + round(m_thumbRect.left), getItemPos(m_pushItemIndex).y() + round(m_thumbRect.top)); painter.fillRect(pt.x(), pt.y(), m_itemSize, m_itemSize + m_itemTextHeight, QColor(0, 0, 0, 96)); } if (-1 != m_curItemIndex) { QPoint pt(getItemPos(m_curItemIndex).x() + round(m_thumbRect.left), getItemPos(m_curItemIndex).y() + round(m_thumbRect.top)); QPen pen(QColor(0, 0, 0, 128)); painter.setPen(pen); painter.drawRect(pt.x(), pt.y(), m_itemSize - 1, m_itemSize + m_itemTextHeight - 1); } if (m_insertPtValid) { QPen pen(QColor(0, 0, 0, 128), 3); painter.setPen(pen); QPoint pt1(m_insertPt1.x() + round(m_thumbRect.left), m_insertPt1.y() + round(m_thumbRect.top)); QPoint pt2(m_insertPt2.x() + round(m_thumbRect.left), m_insertPt2.y() + round(m_thumbRect.top)); painter.drawLine(pt1, pt2); } if (m_frameSelectionRectValid) { QRect rect(m_frameSelectionRect.left + round(m_thumbRect.left), m_frameSelectionRect.top + round(m_thumbRect.top), m_frameSelectionRect.right - m_frameSelectionRect.left, m_frameSelectionRect.bottom - m_frameSelectionRect.top); painter.fillRect(rect, QColor(0, 0, 0, 128)); } DrawScroll(painter); } void HGImgThumb::wheelEvent(QWheelEvent* e) { if (MouseStatus_Null != m_mousePressStatus || 0 != m_operate || m_draging || m_frameSelection) { return; } if (!m_showThumb) { return; } if (QGuiApplication::keyboardModifiers() == Qt::ControlModifier) { if (e->delta() > 0) zoomIn(); else zoomOut(); return; } if (e->delta() > 0) { if (ThumbType_Hori == m_type) { m_thumbRect.left += (double)m_itemSize / 2.0; m_thumbRect.right += (double)m_itemSize / 2.0; } else { m_thumbRect.top += (double)m_itemSize / 2.0; m_thumbRect.bottom += (double)m_itemSize / 2.0; } } else { if (ThumbType_Hori == m_type) { m_thumbRect.left -= (double)m_itemSize / 2.0; m_thumbRect.right -= (double)m_itemSize / 2.0; } else { m_thumbRect.top -= (double)m_itemSize / 2.0; m_thumbRect.bottom -= (double)m_itemSize / 2.0; } } recalcShowRect(this->width(), this->height(), m_scrollSize, m_type, m_hScroll, m_vScroll, m_showThumb, m_thumbRect); m_hotItemIndex = getItemIndex(mapFromGlobal(QCursor::pos()), m_mouseMoveStatus); Show(); } void HGImgThumb::resizeEvent(QResizeEvent* e) { Q_UNUSED(e); reset(); if (m_showThumb) { int showWidth = 0, showHeight = 0; calcShowSize(this->width(), this->height(), m_gapSize, m_scrollSize, m_itemSize, m_itemTextHeight, m_type, (int)m_frontItems.size(), showWidth, showHeight, m_hScroll, m_vScroll); m_thumbRect.right = m_thumbRect.left + (double)showWidth; m_thumbRect.bottom = m_thumbRect.top + (double)showHeight; recalcShowRect(this->width(), this->height(), m_scrollSize, m_type, m_hScroll, m_vScroll, m_showThumb, m_thumbRect); m_hotItemIndex = getItemIndex(mapFromGlobal(QCursor::pos()), m_mouseMoveStatus); } Show(); } void HGImgThumb::keyPressEvent(QKeyEvent *e) { if (MouseStatus_Null != m_mousePressStatus || 0 != m_operate || m_draging || m_frameSelection) { return; } if (m_frontItems.empty()) { return; } if (e->key() != Qt::Key_Left && e->key() != Qt::Key_Right && e->key() != Qt::Key_Up && e->key() != Qt::Key_Down && e->key() != Qt::Key_Home && e->key() != Qt::Key_End && e->key() != Qt::Key_A) { return; } bool emitCurItemChange = false; bool emitItemSelectingChange = false; if (e->key() == Qt::Key_Left) { if (ThumbType_Vert != m_type) { if (QGuiApplication::keyboardModifiers() == Qt::ControlModifier) { // 按住Ctrl什么也不干 } else if (QGuiApplication::keyboardModifiers() == Qt::ShiftModifier) { if (-1 != m_signItemIndex) { if (-1 == m_curItemIndex) { m_curItemIndex = m_signItemIndex; emitCurItemChange = true; } if (m_curItemIndex > 0) { --m_curItemIndex; emitCurItemChange = true; } for (int i = 0; i < (int)m_frontItems.size(); ++i) { if (i >= HGMIN(m_curItemIndex, m_signItemIndex) && i <= HGMAX(m_curItemIndex, m_signItemIndex)) { if (!m_frontItems[i]->selected) emitItemSelectingChange = true; m_frontItems[i]->selected = true; } else { if (m_frontItems[i]->selected) emitItemSelectingChange = true; m_frontItems[i]->selected = false; } } } } else { if (m_curItemIndex > 0) { --m_curItemIndex; emitCurItemChange = true; for (int i = 0; i < (int)m_frontItems.size(); ++i) { if (i == m_curItemIndex) { if (!m_frontItems[i]->selected) emitItemSelectingChange = true; m_frontItems[i]->selected = true; } else { if (m_frontItems[i]->selected) emitItemSelectingChange = true; m_frontItems[i]->selected = false; } } } } } } else if (e->key() == Qt::Key_Right) { if (ThumbType_Vert != m_type) { if (QGuiApplication::keyboardModifiers() == Qt::ControlModifier) { // 按住Ctrl什么也不干 } else if (QGuiApplication::keyboardModifiers() == Qt::ShiftModifier) { if (-1 != m_signItemIndex) { if (-1 == m_curItemIndex) { m_curItemIndex = m_signItemIndex; emitCurItemChange = true; } if (m_curItemIndex < (int)m_frontItems.size() - 1) { ++m_curItemIndex; emitCurItemChange = true; } for (int i = 0; i < (int)m_frontItems.size(); ++i) { if (i >= HGMIN(m_curItemIndex, m_signItemIndex) && i <= HGMAX(m_curItemIndex, m_signItemIndex)) { if (!m_frontItems[i]->selected) emitItemSelectingChange = true; m_frontItems[i]->selected = true; } else { if (m_frontItems[i]->selected) emitItemSelectingChange = true; m_frontItems[i]->selected = false; } } } } else { if (m_curItemIndex != -1 && m_curItemIndex < (int)m_frontItems.size() - 1) { ++m_curItemIndex; emitCurItemChange = true; for (int i = 0; i < (int)m_frontItems.size(); ++i) { if (i == m_curItemIndex) { if (!m_frontItems[i]->selected) emitItemSelectingChange = true; m_frontItems[i]->selected = true; } else { if (m_frontItems[i]->selected) emitItemSelectingChange = true; m_frontItems[i]->selected = false; } } } } } } else if (e->key() == Qt::Key_Up) { if (ThumbType_Hori != m_type) { if (QGuiApplication::keyboardModifiers() == Qt::ControlModifier) { // 按住Ctrl什么也不干 } else if (QGuiApplication::keyboardModifiers() == Qt::ShiftModifier) { if (-1 != m_signItemIndex) { if (-1 == m_curItemIndex) { m_curItemIndex = m_signItemIndex; emitCurItemChange = true; } if (getItemRow(m_curItemIndex) > 0) { m_curItemIndex -= getTotalCols(); emitCurItemChange = true; } for (int i = 0; i < (int)m_frontItems.size(); ++i) { if (i >= HGMIN(m_curItemIndex, m_signItemIndex) && i <= HGMAX(m_curItemIndex, m_signItemIndex)) { if (!m_frontItems[i]->selected) emitItemSelectingChange = true; m_frontItems[i]->selected = true; } else { if (m_frontItems[i]->selected) emitItemSelectingChange = true; m_frontItems[i]->selected = false; } } } } else { if (m_curItemIndex != -1 && getItemRow(m_curItemIndex) > 0) { m_curItemIndex -= getTotalCols(); emitCurItemChange = true; for (int i = 0; i < (int)m_frontItems.size(); ++i) { if (i == m_curItemIndex) { if (!m_frontItems[i]->selected) emitItemSelectingChange = true; m_frontItems[i]->selected = true; } else { if (m_frontItems[i]->selected) emitItemSelectingChange = true; m_frontItems[i]->selected = false; } } } } } } else if (e->key() == Qt::Key_Down) { if (ThumbType_Hori != m_type) { if (QGuiApplication::keyboardModifiers() == Qt::ControlModifier) { // 按住Ctrl什么也不干 } else if (QGuiApplication::keyboardModifiers() == Qt::ShiftModifier) { if (-1 != m_signItemIndex) { if (-1 == m_curItemIndex) { m_curItemIndex = m_signItemIndex; emitCurItemChange = true; } if (getItemRow(m_curItemIndex) < getTotalRows() - 1) { m_curItemIndex = HGMIN(m_curItemIndex + getTotalCols(), (int)m_frontItems.size() - 1); emitCurItemChange = true; } for (int i = 0; i < (int)m_frontItems.size(); ++i) { if (i >= HGMIN(m_curItemIndex, m_signItemIndex) && i <= HGMAX(m_curItemIndex, m_signItemIndex)) { if (!m_frontItems[i]->selected) emitItemSelectingChange = true; m_frontItems[i]->selected = true; } else { if (m_frontItems[i]->selected) emitItemSelectingChange = true; m_frontItems[i]->selected = false; } } } } else { if (m_curItemIndex != -1 && getItemRow(m_curItemIndex) < getTotalRows() - 1) { m_curItemIndex = HGMIN(m_curItemIndex + getTotalCols(), (int)m_frontItems.size() - 1); emitCurItemChange = true; for (int i = 0; i < (int)m_frontItems.size(); ++i) { if (i == m_curItemIndex) { if (!m_frontItems[i]->selected) emitItemSelectingChange = true; m_frontItems[i]->selected = true; } else { if (m_frontItems[i]->selected) emitItemSelectingChange = true; m_frontItems[i]->selected = false; } } } } } } else if (e->key() == Qt::Key_Home) { if (QGuiApplication::keyboardModifiers() == Qt::ControlModifier) { // 按住Ctrl什么也不干 } else if (QGuiApplication::keyboardModifiers() == Qt::ShiftModifier) { if (-1 != m_signItemIndex) { if (0 != m_curItemIndex) { m_curItemIndex = 0; emitCurItemChange = true; } for (int i = 0; i < (int)m_frontItems.size(); ++i) { if (i >= HGMIN(m_curItemIndex, m_signItemIndex) && i <= HGMAX(m_curItemIndex, m_signItemIndex)) { if (!m_frontItems[i]->selected) emitItemSelectingChange = true; m_frontItems[i]->selected = true; } else { if (m_frontItems[i]->selected) emitItemSelectingChange = true; m_frontItems[i]->selected = false; } } } } else { if (0 != m_curItemIndex) { m_curItemIndex = 0; emitCurItemChange = true; } for (int i = 0; i < (int)m_frontItems.size(); ++i) { if (i == m_curItemIndex) { if (!m_frontItems[i]->selected) emitItemSelectingChange = true; m_frontItems[i]->selected = true; } else { if (m_frontItems[i]->selected) emitItemSelectingChange = true; m_frontItems[i]->selected = false; } } } } else if (e->key() == Qt::Key_End) { if (QGuiApplication::keyboardModifiers() == Qt::ControlModifier) { // 按住Ctrl什么也不干 } else if (QGuiApplication::keyboardModifiers() == Qt::ShiftModifier) { if (-1 != m_signItemIndex) { if ((int)m_frontItems.size() - 1 != m_curItemIndex) { m_curItemIndex = (int)m_frontItems.size() - 1; emitCurItemChange = true; } for (int i = 0; i < (int)m_frontItems.size(); ++i) { if (i >= HGMIN(m_curItemIndex, m_signItemIndex) && i <= HGMAX(m_curItemIndex, m_signItemIndex)) { if (!m_frontItems[i]->selected) emitItemSelectingChange = true; m_frontItems[i]->selected = true; } else { if (m_frontItems[i]->selected) emitItemSelectingChange = true; m_frontItems[i]->selected = false; } } } } else { if ((int)m_frontItems.size() - 1 != m_curItemIndex) { m_curItemIndex = (int)m_frontItems.size() - 1; emitCurItemChange = true; } for (int i = 0; i < (int)m_frontItems.size(); ++i) { if (i == m_curItemIndex) { if (!m_frontItems[i]->selected) emitItemSelectingChange = true; m_frontItems[i]->selected = true; } else { if (m_frontItems[i]->selected) emitItemSelectingChange = true; m_frontItems[i]->selected = false; } } } } else if (e->key() == Qt::Key_A) { if (QGuiApplication::keyboardModifiers() == Qt::ControlModifier) { for (int i = 0; i < (int)m_frontItems.size(); ++i) { if (!m_frontItems[i]->selected) emitItemSelectingChange = true; m_frontItems[i]->selected = true; } } } if (-1 != m_curItemIndex) { locateItem(m_curItemIndex); recalcShowRect(this->width(), this->height(), m_scrollSize, m_type, m_hScroll, m_vScroll, m_showThumb, m_thumbRect); m_hotItemIndex = getItemIndex(mapFromGlobal(QCursor::pos()), m_mouseMoveStatus); } Show(); if (emitCurItemChange) emit currItemChanged(m_curItemIndex); if (emitItemSelectingChange) emit itemSelectingChanged(); } void HGImgThumb::keyReleaseEvent(QKeyEvent *e) { Q_UNUSED(e); } void HGImgThumb::focusInEvent(QFocusEvent *e) { Q_UNUSED(e); } void HGImgThumb::focusOutEvent(QFocusEvent *e) { Q_UNUSED(e); } void HGImgThumb::contextMenuEvent(QContextMenuEvent* e) { if (MouseStatus_Null != m_mousePressStatus || 0 != m_operate || m_draging || m_frameSelection) { return; } m_pushItemIndex = -1; MouseStatus mouseMoveStatus = MouseStatus_Null; int index = getItemIndex(e->pos(), mouseMoveStatus); if (MouseStatus_Null == mouseMoveStatus) emit contextMenuEvent(index); } void HGImgThumb::dragEnterEvent(QDragEnterEvent *e) { qDebug("dragEnterEvent"); if (e->mimeData()->hasUrls()) { m_draging = true; e->accept(); } } void HGImgThumb::dragMoveEvent(QDragMoveEvent *e) { //qDebug("dragMoveEvent"); int insertPos = getInsertPos(e->pos(), m_insertPtValid, m_insertPt1, m_insertPt2); if (m_insertPtValid && m_curInsertPos != insertPos) { locateInsert(m_insertPt1, m_insertPt2); recalcShowRect(this->width(), this->height(), m_scrollSize, m_type, m_hScroll, m_vScroll, m_showThumb, m_thumbRect); } if (m_curInsertPos != insertPos) qDebug("current insert pos=%d", insertPos); m_curInsertPos = insertPos; Show(); } void HGImgThumb::dragLeaveEvent(QDragLeaveEvent *e) { qDebug("dragLeaveEvent"); Q_UNUSED(e); m_curInsertPos = -1; m_insertPtValid = false; m_draging = false; Show(); } void HGImgThumb::dropEvent(QDropEvent *e) { QStringList fileNames; QList urls = e->mimeData()->urls(); for (QUrl url : urls) { fileNames.append(url.toLocalFile()); } int pos = m_curInsertPos; m_curInsertPos = -1; m_insertPtValid = false; m_draging = false; m_hotItemIndex = getItemIndex(mapFromGlobal(QCursor::pos()), m_mouseMoveStatus); Show(); emit drop(e->source(), fileNames, pos); } void HGImgThumb::mouseDoubleClickEvent(QMouseEvent *e) { if (MouseStatus_Null != m_mousePressStatus || 0 != m_operate || m_draging || m_frameSelection) { return; } MouseStatus mouseMoveStatus = MouseStatus_Null; int index = getItemIndex(e->pos(), mouseMoveStatus); if (MouseStatus_Null == mouseMoveStatus && -1 != index) { if (m_curItemIndex == index && m_frontItems[index]->selected) emit itemDoubleClicked(index); } else { QWidget::mouseDoubleClickEvent(e); } } void HGImgThumb::on_updateItem() { Show(); } QImage* HGImgThumb::createItemImage(const QImage *srcImage, int itemSize) { assert(nullptr != srcImage); QImage *img = nullptr; if (srcImage->width() > itemSize || srcImage->height() > itemSize) { int width, height; if (srcImage->width() < srcImage->height()) { height = itemSize; width = height * srcImage->width() / srcImage->height(); } else { width = itemSize; height = width * srcImage->height() / srcImage->width(); } assert(width != srcImage->width() || height != srcImage->height()); img = new QImage(srcImage->scaled(width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); } else { img = new QImage(srcImage->copy(0, 0, srcImage->width(), srcImage->height())); } if (img->isNull()) { delete img; return nullptr; } return img; } QImage* HGImgThumb::createItemImage(HGImage srcImage, int itemSize) { assert(nullptr != srcImage); HGImageInfo info; HGBase_GetImageInfo(srcImage, &info); QImage::Format fmt = QImage::Format_Invalid; if (info.type == HGBASE_IMGTYPE_BINARY) fmt = QImage::Format_Mono; else if (info.type == HGBASE_IMGTYPE_GRAY) fmt = QImage::Format_Grayscale8; else if (info.type == HGBASE_IMGTYPE_RGB) fmt = QImage::Format_RGB888; else if (info.type == HGBASE_IMGTYPE_RGBA) fmt = QImage::Format_RGBA8888; if (QImage::Format_Invalid == fmt) { return nullptr; } HGByte *data = nullptr; HGBase_GetImageData(srcImage, &data); QImage img(data, info.width, info.height, info.widthStep, fmt); if (img.isNull()) { return nullptr; } if (img.format() == QImage::Format_Mono) img = img.convertToFormat(QImage::Format_Grayscale8); return createItemImage(&img, itemSize); } void HGImgThumb::DrawImage(QPainter &painter, const QRect &destRect, const QImage *image, const QRect &stretchRect) { if (destRect.width() < image->width() - stretchRect.width() || destRect.height() < image->height() - stretchRect.height()) { painter.drawImage(destRect, *image); return; } for (int i = 0; i < 9; ++i) { int DestX = destRect.left(), DestY = destRect.top(), DestWidth = destRect.width(), DestHeight = destRect.height(); int SrcX = 0, SrcY = 0, SrcWidth = image->width(), SrcHeight = image->height(); if (0 == i % 3) { DestX = destRect.left(); DestWidth = stretchRect.left(); SrcX = 0; SrcWidth = stretchRect.left(); } else if (1 == i % 3) { DestX = destRect.left() + stretchRect.left(); DestWidth = destRect.width() + stretchRect.width() - image->width(); SrcX = stretchRect.left(); SrcWidth = stretchRect.width(); } else if (2 == i % 3) { DestX = destRect.left() + destRect.width() + stretchRect.left() + stretchRect.width() - image->width(); DestWidth = image->width() - (stretchRect.left() + stretchRect.width()); SrcX = stretchRect.left() + stretchRect.width(); SrcWidth = image->width() - (stretchRect.left() + stretchRect.width()); } if (0 == i / 3) { DestY = destRect.top(); DestHeight = stretchRect.top(); SrcY = 0; SrcHeight = stretchRect.top(); } else if (1 == i / 3) { DestY = destRect.top() + stretchRect.top(); DestHeight = destRect.height() + stretchRect.height() - image->height(); SrcY = stretchRect.top(); SrcHeight = stretchRect.height(); } else if (2 == i / 3) { DestY = destRect.top() + destRect.height() + stretchRect.top() + stretchRect.height() - image->height(); DestHeight = image->height() - (stretchRect.top() + stretchRect.height()); SrcY = stretchRect.top() + stretchRect.height(); SrcHeight = image->height() - (stretchRect.top() + stretchRect.height()); } QRect dest(DestX, DestY, DestWidth, DestHeight); QRect src(SrcX, SrcY, SrcWidth, SrcHeight); painter.drawImage(dest, *image, src); } } void HGImgThumb::calcShowSize(int wndWidth, int wndHeight, int gapSize, int scrollSize, int itemSize, int itemTextHeight, ThumbType type, int itemCount, int &showWidth, int &showHeight, bool &hScroll, bool &vScroll) { showWidth = 0; showHeight = 0; hScroll = false; vScroll = false; if (itemCount <= 0) { return; } if (ThumbType_Hori == type) { showWidth = gapSize + itemCount * (itemSize + gapSize); showHeight = gapSize * 2 + itemSize + itemTextHeight; if (showHeight > wndHeight) { vScroll = true; if (showWidth > wndWidth - scrollSize) hScroll = true; } else { if (showWidth > wndWidth) { hScroll = true; if (showHeight > wndHeight - scrollSize) vScroll = true; } } } else if (ThumbType_Vert == type) { showWidth = gapSize * 2 + itemSize; showHeight = gapSize + itemCount * (itemSize + itemTextHeight + gapSize); if (showHeight > wndHeight) { vScroll = true; if (showWidth > wndWidth - scrollSize) hScroll = true; } else { if (showWidth > wndWidth) { hScroll = true; if (showHeight > wndHeight - scrollSize) vScroll = true; } } } else { int cols = HGMIN(itemCount, HGMAX(1, (wndWidth - gapSize) / (itemSize + gapSize))); showWidth = gapSize + cols * (itemSize + gapSize); int rows = (itemCount - 1) / cols + 1; showHeight = gapSize + rows * (itemSize + itemTextHeight + gapSize); if (showHeight > wndHeight) { cols = HGMIN(itemCount, HGMAX(1, (wndWidth - scrollSize - gapSize) / (itemSize + gapSize))); showWidth = gapSize + cols * (itemSize + gapSize); rows = (itemCount - 1) / cols + 1; showHeight = gapSize + rows * (itemSize + itemTextHeight + gapSize); assert(showHeight > wndHeight); vScroll = true; if (showWidth > wndWidth - scrollSize) hScroll = true; } else { if (showWidth > wndWidth) { hScroll = true; if (showHeight > wndHeight - scrollSize) vScroll = true; } } } } void HGImgThumb::recalcShowRect(int wndWidth, int wndHeight, int scrollSize, ThumbType type, bool hScroll, bool vScroll, bool showThumb, ThumbRect &thumbRect) { if (!showThumb) return; double width = thumbRect.right - thumbRect.left; double height = thumbRect.bottom - thumbRect.top; // 调整 if (ThumbType_Hori == type) { if (!vScroll) // 没有垂直滚动条 { if (hScroll) // 有水平滚动条 thumbRect.top = (double)(wndHeight - scrollSize - height) / 2.0; else // 没有水平滚动条 thumbRect.top = (double)(wndHeight - height) / 2.0; thumbRect.bottom = thumbRect.top + height; } else // 有垂直滚动条 { int hScrollSize = hScroll ? scrollSize : 0; if (thumbRect.bottom < (double)(wndHeight - hScrollSize)) { thumbRect.bottom = wndHeight - hScrollSize; thumbRect.top = thumbRect.bottom - height; } if (thumbRect.top > 0) { thumbRect.top = 0; thumbRect.bottom = thumbRect.top + height; } } int vScrollSize = vScroll ? scrollSize : 0; if (thumbRect.right < (double)(wndWidth - vScrollSize)) { thumbRect.right = wndWidth - vScrollSize; thumbRect.left = thumbRect.right - width; } if (thumbRect.left > 0) { thumbRect.left = 0; thumbRect.right = thumbRect.left + width; } } else if (ThumbType_Vert == type) { if (!hScroll) // 没有水平滚动条 { if (vScroll) // 有垂直滚动条 thumbRect.left = (double)(wndWidth - scrollSize - width) / 2.0; else // 没有垂直滚动条 thumbRect.left = (double)(wndWidth - width) / 2.0; thumbRect.right = thumbRect.left + width; } else // 有水平滚动条 { int vScrollSize = vScroll ? scrollSize : 0; if (thumbRect.right < (double)(wndWidth - vScrollSize)) { thumbRect.right = wndWidth - vScrollSize; thumbRect.left = thumbRect.right - width; } if (thumbRect.left > 0) { thumbRect.left = 0; thumbRect.right = thumbRect.left + width; } } int hScrollSize = hScroll ? scrollSize : 0; if (thumbRect.bottom < (double)(wndHeight - hScrollSize)) { thumbRect.bottom = wndHeight - hScrollSize; thumbRect.top = thumbRect.bottom - height; } if (thumbRect.top > 0) { thumbRect.top = 0; thumbRect.bottom = thumbRect.top + height; } } else { int vScrollSize = vScroll ? scrollSize : 0; if (thumbRect.right < (double)(wndWidth - vScrollSize)) { thumbRect.right = wndWidth - vScrollSize; thumbRect.left = thumbRect.right - width; } if (thumbRect.left > 0) { thumbRect.left = 0; thumbRect.right = thumbRect.left + width; } int hScrollSize = hScroll ? scrollSize : 0; if (thumbRect.bottom < (double)(wndHeight - hScrollSize)) { thumbRect.bottom = wndHeight - hScrollSize; thumbRect.top = thumbRect.bottom - height; } if (thumbRect.top > 0) { thumbRect.top = 0; thumbRect.bottom = thumbRect.top + height; } } } void HGImgThumb::DrawScroll(QPainter &painter) { // 滚动条背景 QColor clrHScroll = qRgb(220, 220, 220); QImage *imgHScroll = m_hScrollImage; QColor clrVScroll = qRgb(220, 220, 220); QImage *imgVScroll = m_vScrollImage; QColor clrNullScroll = qRgb(255, 255, 255); QImage *nullScrollImage = m_nullScrollImage; // 水平滑块 QColor clrHScrollSlider = qRgb(180, 180, 180); QImage *imgHScrollSlider = m_hScrollSliderImage[0]; QRect hScrollSliderStretch = m_hScrollSliderImageStretch[0]; if (MouseStatus_HScrollSlider == m_mousePressStatus) { clrHScrollSlider = qRgb(100, 100, 100); imgHScrollSlider = m_hScrollSliderImage[2]; hScrollSliderStretch = m_hScrollSliderImageStretch[2]; } else if (MouseStatus_HScrollLeft == m_mousePressStatus || MouseStatus_HScrollRight == m_mousePressStatus || MouseStatus_HScroll == m_mousePressStatus || MouseStatus_HScrollSlider == m_mouseMoveStatus || MouseStatus_HScroll == m_mouseMoveStatus || MouseStatus_HScrollLeft == m_mouseMoveStatus || MouseStatus_HScrollRight == m_mouseMoveStatus) { clrHScrollSlider = qRgb(140, 140, 140); imgHScrollSlider = m_hScrollSliderImage[1]; hScrollSliderStretch = m_hScrollSliderImageStretch[1]; } // 垂直滑块 QColor clrVScrollSlider = qRgb(180, 180, 180); QImage *imgVScrollSlider = m_vScrollSliderImage[0]; QRect vScrollSliderStretch = m_vScrollSliderImageStretch[0]; if (MouseStatus_VScrollSlider == m_mousePressStatus) { clrVScrollSlider = qRgb(100, 100, 100); imgVScrollSlider = m_vScrollSliderImage[2]; vScrollSliderStretch = m_vScrollSliderImageStretch[2]; } else if (MouseStatus_VScrollTop == m_mousePressStatus || MouseStatus_VScrollBottom == m_mousePressStatus || MouseStatus_VScroll == m_mousePressStatus || MouseStatus_VScrollSlider == m_mouseMoveStatus || MouseStatus_VScroll == m_mouseMoveStatus || MouseStatus_VScrollTop == m_mouseMoveStatus || MouseStatus_VScrollBottom == m_mouseMoveStatus) { clrVScrollSlider = qRgb(140, 140, 140); imgVScrollSlider = m_vScrollSliderImage[1]; vScrollSliderStretch = m_vScrollSliderImageStretch[1]; } // 水平左键 QColor clrHScrollLeft = qRgb(220, 220, 220); QImage *imgHScrollLeft = m_hScrollLeftImage[0]; if (MouseStatus_HScrollLeft == m_mousePressStatus) { clrHScrollLeft = qRgb(140, 140, 140); imgHScrollLeft = m_hScrollLeftImage[2]; } else if (MouseStatus_HScrollRight == m_mousePressStatus || MouseStatus_HScrollSlider == m_mousePressStatus || MouseStatus_HScroll == m_mousePressStatus || MouseStatus_HScrollSlider == m_mouseMoveStatus || MouseStatus_HScroll == m_mouseMoveStatus || MouseStatus_HScrollLeft == m_mouseMoveStatus || MouseStatus_HScrollRight == m_mouseMoveStatus) { clrHScrollLeft = qRgb(180, 180, 180); imgHScrollLeft = m_hScrollLeftImage[1]; } // 水平右键 QColor clrHScrollRight = qRgb(220, 220, 220); QImage *imgHScrollRight = m_hScrollRightImage[0]; if (MouseStatus_HScrollRight == m_mousePressStatus) { clrHScrollRight = qRgb(140, 140, 140); imgHScrollRight = m_hScrollRightImage[2]; } else if (MouseStatus_HScrollLeft == m_mousePressStatus || MouseStatus_HScrollSlider == m_mousePressStatus || MouseStatus_HScroll == m_mousePressStatus || MouseStatus_HScrollSlider == m_mouseMoveStatus || MouseStatus_HScroll == m_mouseMoveStatus || MouseStatus_HScrollLeft == m_mouseMoveStatus || MouseStatus_HScrollRight == m_mouseMoveStatus) { clrHScrollRight = qRgb(180, 180, 180); imgHScrollRight = m_hScrollRightImage[1]; } // 垂直上键 QColor clrVScrollTop = qRgb(220, 220, 220); QImage *imgVScrollTop = m_vScrollTopImage[0]; if (MouseStatus_VScrollTop == m_mousePressStatus) { clrVScrollTop = qRgb(140, 140, 140); imgVScrollTop = m_vScrollTopImage[2]; } else if (MouseStatus_VScrollSlider == m_mousePressStatus || MouseStatus_VScrollBottom == m_mousePressStatus || MouseStatus_VScroll == m_mousePressStatus || MouseStatus_VScrollSlider == m_mouseMoveStatus || MouseStatus_VScroll == m_mouseMoveStatus || MouseStatus_VScrollTop == m_mouseMoveStatus || MouseStatus_VScrollBottom == m_mouseMoveStatus) { clrVScrollTop = qRgb(180, 180, 180); imgVScrollTop = m_vScrollTopImage[1]; } // 垂直下键 QColor clrVScrollBottom = qRgb(220, 220, 220); QImage *imgVScrollBottom = m_vScrollBottomImage[0]; if (MouseStatus_VScrollBottom == m_mousePressStatus) { clrVScrollBottom = qRgb(140, 140, 140); imgVScrollBottom = m_vScrollBottomImage[2]; } else if (MouseStatus_VScrollSlider == m_mousePressStatus || MouseStatus_VScrollTop == m_mousePressStatus || MouseStatus_VScroll == m_mousePressStatus || MouseStatus_VScrollSlider == m_mouseMoveStatus || MouseStatus_VScroll == m_mouseMoveStatus || MouseStatus_VScrollTop == m_mouseMoveStatus || MouseStatus_VScrollBottom == m_mouseMoveStatus) { clrVScrollBottom = qRgb(180, 180, 180); imgVScrollBottom = m_vScrollBottomImage[1]; } if (m_hScroll) { if (nullptr == imgHScroll) painter.fillRect(getHScrollPos(), clrHScroll); else DrawImage(painter, getHScrollPos(), imgHScroll, m_hScrollImageStretch); if (nullptr == imgHScrollLeft) painter.fillRect(getHScrollLeftPos(), clrHScrollLeft); else painter.drawImage(getHScrollLeftPos(), *imgHScrollLeft); if (nullptr == imgHScrollRight) painter.fillRect(getHScrollRightPos(), clrHScrollRight); else painter.drawImage(getHScrollRightPos(), *imgHScrollRight); if (nullptr == imgHScrollSlider) painter.fillRect(getHScrollSliderPos(), clrHScrollSlider); else DrawImage(painter, getHScrollSliderPos(), imgHScrollSlider, hScrollSliderStretch); } if (m_vScroll) { if (nullptr == imgVScroll) painter.fillRect(getVScrollPos(), clrVScroll); else DrawImage(painter, getVScrollPos(), imgVScroll, m_vScrollImageStretch); if (nullptr == imgVScrollTop) painter.fillRect(getVScrollTopPos(), clrVScrollTop); else painter.drawImage(getVScrollTopPos(), *imgVScrollTop); if (nullptr == imgVScrollBottom) painter.fillRect(getVScrollBottomPos(), clrVScrollBottom); else painter.drawImage(getVScrollBottomPos(), *imgVScrollBottom); if (nullptr == imgVScrollSlider) painter.fillRect(getVScrollSliderPos(), clrVScrollSlider); else DrawImage(painter, getVScrollSliderPos(), imgVScrollSlider, vScrollSliderStretch); } if (m_hScroll && m_vScroll) { if (nullptr == nullScrollImage) painter.fillRect(getNullScrollPos(), clrNullScroll); else painter.drawImage(getNullScrollPos(), *nullScrollImage); } } void HGImgThumb::reset() { m_frameSelectionRectValid = false; m_frameSelection = false; m_curInsertPos = -1; m_insertPtValid = false; m_draging = false; m_pushItemIndex = -1; m_operateStartX = -1; m_operateStartY = -1; m_operate = 0; m_hitMouseButtons = Qt::NoButton; m_hitKeyboardModifiers = Qt::NoModifier; m_hitItemIndex = -1; m_mousePressStatus = MouseStatus_Null; m_mousePressBeginX = -1; m_mousePressBeginY = -1; } QPoint HGImgThumb::getItemPos(int index) { assert(index >= 0 && index < (int)m_frontItems.size()); assert(m_showThumb); int x, y; if (ThumbType_Hori == m_type) { x = m_gapSize + index * (m_itemSize + m_gapSize); y = m_gapSize; } else if (ThumbType_Vert == m_type) { x = m_gapSize; y = m_gapSize + index * (m_itemSize + m_itemTextHeight + m_gapSize); } else { int cols = round((m_thumbRect.right - m_thumbRect.left - m_gapSize) / (m_itemSize + m_gapSize)); x = m_gapSize + (index % cols) * (m_itemSize + m_gapSize); y = m_gapSize + (index / cols) * (m_itemSize + m_itemTextHeight + m_gapSize); } QPoint pt(x, y); return pt; } void HGImgThumb::locateItem(int index) { assert(index >= 0 && index < (int)m_frontItems.size()); assert(m_showThumb); int left = getItemPos(index).x() + round(m_thumbRect.left); int top = getItemPos(index).y() + round(m_thumbRect.top); int right = left + m_itemSize; int bottom = top + m_itemSize + m_itemTextHeight; int scrollWidth; int gap; scrollWidth = m_vScroll ? m_scrollSize : 0; gap = m_gapSize; if (left < gap && right + (gap - left) <= (this->width() - scrollWidth - m_gapSize)) { m_thumbRect.left += (gap - left); m_thumbRect.right += (gap - left); } else if (right > (this->width() - scrollWidth - gap) && left - (right - this->width() + scrollWidth + gap) >= m_gapSize) { m_thumbRect.left -= (right - this->width() + scrollWidth + gap); m_thumbRect.right -= (right - this->width() + scrollWidth + gap); } scrollWidth = m_hScroll ? m_scrollSize : 0; gap = m_gapSize; if (top < gap && bottom + (gap - top) <= (this->height() - scrollWidth - m_gapSize)) { m_thumbRect.top += (gap - top); m_thumbRect.bottom += (gap - top); } else if (bottom > (this->height() - scrollWidth - gap) && top - (bottom - this->height() + scrollWidth + gap) >= m_gapSize) { m_thumbRect.top -= (bottom - this->height() + scrollWidth + gap); m_thumbRect.bottom -= (bottom - this->height() + scrollWidth + gap); } } void HGImgThumb::locateInsert(const QPoint &pt1, const QPoint &pt2) { int left = HGMIN(pt1.x(), pt2.x()) + round(m_thumbRect.left); int top = HGMIN(pt1.y(), pt2.y()) + round(m_thumbRect.top); int right = HGMAX(pt1.x(), pt2.x()) + round(m_thumbRect.left); int bottom = HGMAX(pt1.y(), pt2.y()) + round(m_thumbRect.top); int scrollWidth; int gap; scrollWidth = m_vScroll ? m_scrollSize : 0; gap = m_gapSize; if (left < gap && right + (gap - left) <= (this->width() - scrollWidth - m_gapSize)) { int value = gap - left; m_thumbRect.left += value; m_thumbRect.right += value; } else if (right > (this->width() - scrollWidth - gap) && left - (right - this->width() + scrollWidth + gap) >= m_gapSize) { int value = right - this->width() + scrollWidth + gap; m_thumbRect.left -= value; m_thumbRect.right -= value; } scrollWidth = m_hScroll ? m_scrollSize : 0; gap = m_gapSize; if (top < gap && bottom + (gap - top) <= (this->height() - scrollWidth - m_gapSize)) { int value = gap - top; m_thumbRect.top += value; m_thumbRect.bottom += value; } else if (bottom > (this->height() - scrollWidth - gap) && top - (bottom - this->height() + scrollWidth + gap) >= m_gapSize) { int value = bottom - this->height() + scrollWidth + gap; m_thumbRect.top -= value; m_thumbRect.bottom -= value; } } int HGImgThumb::getItemRow(int index) { assert(index >= 0 && index < (int)m_frontItems.size()); assert(m_showThumb); int row; if (ThumbType_Hori == m_type) { row = 0; } else if (ThumbType_Vert == m_type) { row = index; } else { int cols = round((m_thumbRect.right - m_thumbRect.left - m_gapSize) / (m_itemSize + m_gapSize)); row = index / cols; } return row; } int HGImgThumb::getItemCol(int index) { assert(index >= 0 && index < (int)m_frontItems.size()); assert(m_showThumb); int col; if (ThumbType_Hori == m_type) { col = index; } else if (ThumbType_Vert == m_type) { col = 0; } else { int cols = round((m_thumbRect.right - m_thumbRect.left - m_gapSize) / (m_itemSize + m_gapSize)); col = index % cols; } return col; } int HGImgThumb::getTotalRows() { if (!m_showThumb) { assert(0 == m_frontItems.size()); return 0; } int rows; if (ThumbType_Hori == m_type) { rows = 1; } else if (ThumbType_Vert == m_type) { rows = (int)m_frontItems.size(); } else { rows = round((m_thumbRect.bottom - m_thumbRect.top - m_gapSize) / (m_itemSize + m_itemTextHeight + m_gapSize)); } return rows; } int HGImgThumb::getTotalCols() { if (!m_showThumb) { assert(0 == m_frontItems.size()); return 0; } int cols; if (ThumbType_Hori == m_type) { cols = (int)m_frontItems.size(); } else if (ThumbType_Vert == m_type) { cols = 1; } else { cols = round((m_thumbRect.right - m_thumbRect.left - m_gapSize) / (m_itemSize + m_gapSize)); } return cols; } int HGImgThumb::getRowCount(int row) { assert(row >= 0 && row < getTotalRows()); int count; if (ThumbType_Hori == m_type) { count = (int)m_frontItems.size(); } else if (ThumbType_Vert == m_type) { count = 1; } else { int cols = round((m_thumbRect.right - m_thumbRect.left - m_gapSize) / (m_itemSize + m_gapSize)); if ((row + 1) * cols <= (int)m_frontItems.size()) { count = cols; } else { count = (int)m_frontItems.size() - row * cols; } } return count; } int HGImgThumb::getItemIndex(const QPoint &pt, MouseStatus &mouseStatus) { mouseStatus = MouseStatus_Null; if (!m_showThumb) { assert(0 == m_frontItems.size()); return -1; } if (MouseStatus_Null != m_mousePressStatus || 0 != m_operate || m_draging || m_frameSelection) { return -1; } if (!m_mouseOn) { return -1; } if (m_hScroll && m_vScroll) { if (getHScrollSliderPos().contains(pt)) mouseStatus = MouseStatus_HScrollSlider; else if (getHScrollLeftPos().contains(pt)) mouseStatus = MouseStatus_HScrollLeft; else if (getHScrollRightPos().contains(pt)) mouseStatus = MouseStatus_HScrollRight; else if (getHScrollPos().contains(pt)) mouseStatus = MouseStatus_HScroll; else if (getVScrollSliderPos().contains(pt)) mouseStatus = MouseStatus_VScrollSlider; else if (getVScrollTopPos().contains(pt)) mouseStatus = MouseStatus_VScrollTop; else if (getVScrollBottomPos().contains(pt)) mouseStatus = MouseStatus_VScrollBottom; else if (getVScrollPos().contains(pt)) mouseStatus = MouseStatus_VScroll; else if (getNullScrollPos().contains(pt)) mouseStatus = MouseStatus_NullScroll; } else if (m_hScroll && !m_vScroll) { if (getHScrollSliderPos().contains(pt)) mouseStatus = MouseStatus_HScrollSlider; else if (getHScrollLeftPos().contains(pt)) mouseStatus = MouseStatus_HScrollLeft; else if (getHScrollRightPos().contains(pt)) mouseStatus = MouseStatus_HScrollRight; else if (getHScrollPos().contains(pt)) mouseStatus = MouseStatus_HScroll; } else if (!m_hScroll && m_vScroll) { if (getVScrollSliderPos().contains(pt)) mouseStatus = MouseStatus_VScrollSlider; else if (getVScrollTopPos().contains(pt)) mouseStatus = MouseStatus_VScrollTop; else if (getVScrollBottomPos().contains(pt)) mouseStatus = MouseStatus_VScrollBottom; else if (getVScrollPos().contains(pt)) mouseStatus = MouseStatus_VScroll; } if (MouseStatus_Null != mouseStatus) { return -1; } int index = -1; for (int i = 0; i < (int)m_frontItems.size(); ++i) { int left = getItemPos(i).x() + round(m_thumbRect.left); int top = getItemPos(i).y() + round(m_thumbRect.top); int right = left + m_itemSize; int bottom = top + m_itemSize + m_itemTextHeight; if (pt.x() >= left && pt.y() >= top && pt.x() < right && pt.y() < bottom) { index = i; break; } } return index; } int HGImgThumb::getInsertPos(const QPoint &pt, bool &get, QPoint &pt1, QPoint &pt2) { get = false; if (!m_draging) { return -1; } MouseStatus mouseStatus = MouseStatus_Null; if (m_hScroll && m_vScroll) { if (getHScrollSliderPos().contains(pt)) mouseStatus = MouseStatus_HScrollSlider; else if (getHScrollLeftPos().contains(pt)) mouseStatus = MouseStatus_HScrollLeft; else if (getHScrollRightPos().contains(pt)) mouseStatus = MouseStatus_HScrollRight; else if (getHScrollPos().contains(pt)) mouseStatus = MouseStatus_HScroll; else if (getVScrollSliderPos().contains(pt)) mouseStatus = MouseStatus_VScrollSlider; else if (getVScrollTopPos().contains(pt)) mouseStatus = MouseStatus_VScrollTop; else if (getVScrollBottomPos().contains(pt)) mouseStatus = MouseStatus_VScrollBottom; else if (getVScrollPos().contains(pt)) mouseStatus = MouseStatus_VScroll; else if (getNullScrollPos().contains(pt)) mouseStatus = MouseStatus_NullScroll; } else if (m_hScroll && !m_vScroll) { if (getHScrollSliderPos().contains(pt)) mouseStatus = MouseStatus_HScrollSlider; else if (getHScrollLeftPos().contains(pt)) mouseStatus = MouseStatus_HScrollLeft; else if (getHScrollRightPos().contains(pt)) mouseStatus = MouseStatus_HScrollRight; else if (getHScrollPos().contains(pt)) mouseStatus = MouseStatus_HScroll; } else if (!m_hScroll && m_vScroll) { if (getVScrollSliderPos().contains(pt)) mouseStatus = MouseStatus_VScrollSlider; else if (getVScrollTopPos().contains(pt)) mouseStatus = MouseStatus_VScrollTop; else if (getVScrollBottomPos().contains(pt)) mouseStatus = MouseStatus_VScrollBottom; else if (getVScrollPos().contains(pt)) mouseStatus = MouseStatus_VScroll; } if (MouseStatus_Null != mouseStatus) { return -1; } if (!m_showThumb) { assert(0 == m_frontItems.size()); return 0; } int pos = -1; int x1, x2, y1, y2; if (ThumbType_Hori == m_type) { pos = (int)m_frontItems.size(); QPoint pt2 = getItemPos(pos - 1); x1 = x2 = pt2.x() + m_itemSize + m_gapSize / 2; y1 = pt2.y(); y2 = y1 + m_itemSize + m_itemTextHeight; for (int i = 0; i < (int)m_frontItems.size(); ++i) { QPoint pt2 = getItemPos(i); int left = pt2.x(); int right = left + m_itemSize; if (pt.x() - round(m_thumbRect.left) < (left + right) / 2) { pos = i; x1 = x2 = pt2.x() - m_gapSize / 2; y1 = pt2.y(); y2 = y1 + m_itemSize + m_itemTextHeight; break; } } } else if (ThumbType_Vert == m_type) { pos = (int)m_frontItems.size(); QPoint pt2 = getItemPos(pos - 1); y1 = y2 = pt2.y() + m_itemSize + m_itemTextHeight + m_gapSize / 2; x1 = pt2.x(); x2 = x1 + m_itemSize; for (int i = 0; i < (int)m_frontItems.size(); ++i) { QPoint pt2 = getItemPos(i); int top = pt2.y(); int bottom = top + m_itemSize + m_itemTextHeight; if (pt.y() - round(m_thumbRect.top) < (top + bottom) / 2) { pos = i; y1 = y2 = pt2.y() - m_gapSize / 2; x1 = pt2.x(); x2 = x1 + m_itemSize; break; } } } else { int rows = getTotalRows(); int cols = getTotalCols(); int row = rows; for (int i = 0; i < rows; ++i) { QPoint pt2 = getItemPos(cols * i); int top = pt2.y(); int bottom = top + m_itemSize + m_itemTextHeight; if (pt.y() - round(m_thumbRect.top) < bottom + m_gapSize / 2) { row = i; break; } } if (row == rows) { pos = (int)m_frontItems.size(); QPoint pt2 = getItemPos(pos - 1); x1 = x2 = pt2.x() + m_itemSize + m_gapSize / 2; y1 = pt2.y(); y2 = y1 + m_itemSize + m_itemTextHeight; } else { pos = row * cols + getRowCount(row); QPoint pt2 = getItemPos(row * cols + getRowCount(row) - 1); x1 = x2 = pt2.x() + m_itemSize + m_gapSize / 2; y1 = pt2.y(); y2 = y1 + m_itemSize + m_itemTextHeight; for (int i = 0; i < getRowCount(row); ++i) { QPoint pt2 = getItemPos(row * cols + i); int left = pt2.x(); int right = left + m_itemSize; if (pt.x() - round(m_thumbRect.left) < (left + right) / 2) { pos = row * cols + i; x1 = x2 = pt2.x() - m_gapSize / 2; y1 = pt2.y(); y2 = y1 + m_itemSize + m_itemTextHeight; break; } } } } assert(-1 != pos); get = true; pt1.setX(x1); pt1.setY(y1); pt2.setX(x2); pt2.setY(y2); return pos; } int HGImgThumb::findIndex(const QString &fileName) { int index = -1; for (int i = 0; i < (int)m_frontItems.size(); ++i) { if (0 == m_frontItems[i]->fileName.compare(fileName)) { index = i; break; } } return index; } QRect HGImgThumb::getHScrollLeftPos() { assert(m_hScroll); return QRect(0, this->height() - m_scrollSize, m_scrollSize, m_scrollSize); } QRect HGImgThumb::getHScrollRightPos() { assert(m_hScroll); if (!m_vScroll) { return QRect(this->width() - m_scrollSize, this->height() - m_scrollSize, m_scrollSize, m_scrollSize); } return QRect(this->width() - 2 * m_scrollSize, this->height() - m_scrollSize, m_scrollSize, m_scrollSize); } QRect HGImgThumb::getHScrollPos() { assert(m_hScroll); if (!m_vScroll) { return QRect(0, this->height() - m_scrollSize, this->width(), m_scrollSize); } return QRect(0, this->height() - m_scrollSize, this->width() - m_scrollSize, m_scrollSize); } QRect HGImgThumb::getHScrollSliderPos() { assert(m_hScroll); QRect rect; rect.setY(this->height() - m_scrollSize); rect.setHeight(m_scrollSize); if (!m_vScroll) { int rollTotalLen = this->width() - 2 * m_scrollSize; int rollLeft = round((double)rollTotalLen * (-m_thumbRect.left) / (double)(m_thumbRect.right - m_thumbRect.left)); int rollRight = round((double)rollTotalLen * (-m_thumbRect.left + this->width()) / (double)(m_thumbRect.right - m_thumbRect.left)); int rollLen = rollRight - rollLeft; if (rollLen < m_minScrollSliderSize) { rollLen = m_minScrollSliderSize; rollLeft = round((double)(rollTotalLen - m_minScrollSliderSize) * (-m_thumbRect.left) / (double)(m_thumbRect.right - m_thumbRect.left - this->width())); } rect.setX(rollLeft + m_scrollSize); rect.setWidth(rollLen); } else { int rollTotalLen = this->width() - 3 * m_scrollSize; int rollLeft = round((double)rollTotalLen * (-m_thumbRect.left) / (double)(m_thumbRect.right - m_thumbRect.left)); int rollRight = round((double)rollTotalLen * (-m_thumbRect.left + this->width() - m_scrollSize) / (double)(m_thumbRect.right - m_thumbRect.left)); int rollLen = rollRight - rollLeft; if (rollLen < m_minScrollSliderSize) { rollLen = m_minScrollSliderSize; rollLeft = round((double)(rollTotalLen - m_minScrollSliderSize) * (-m_thumbRect.left) / (double)(m_thumbRect.right - m_thumbRect.left - this->width() + m_scrollSize)); } rect.setX(rollLeft + m_scrollSize); rect.setWidth(rollLen); } return rect; } QRect HGImgThumb::getVScrollTopPos() { assert(m_vScroll); return QRect(this->width() - m_scrollSize, 0, m_scrollSize, m_scrollSize); } QRect HGImgThumb::getVScrollBottomPos() { assert(m_vScroll); if (!m_hScroll) { return QRect(this->width() - m_scrollSize, this->height() - m_scrollSize, m_scrollSize, m_scrollSize); } return QRect(this->width() - m_scrollSize, this->height() - 2 * m_scrollSize, m_scrollSize, m_scrollSize); } QRect HGImgThumb::getVScrollPos() { assert(m_vScroll); if (!m_hScroll) { return QRect(this->width() - m_scrollSize, 0, m_scrollSize, this->height()); } return QRect(this->width() - m_scrollSize, 0, m_scrollSize, this->height() - m_scrollSize); } QRect HGImgThumb::getVScrollSliderPos() { assert(m_vScroll); QRect rect; rect.setX(this->width() - m_scrollSize); rect.setWidth(m_scrollSize); if (!m_hScroll) { int rollTotalLen = this->height() - 2 * m_scrollSize; int rollTop = round((double)rollTotalLen * (-m_thumbRect.top) / (double)(m_thumbRect.bottom - m_thumbRect.top)); int rollBottom = round((double)rollTotalLen * (-m_thumbRect.top + this->height()) / (double)(m_thumbRect.bottom - m_thumbRect.top)); int rollLen = rollBottom - rollTop; if (rollLen < m_minScrollSliderSize) { rollLen = m_minScrollSliderSize; rollTop = round((double)(rollTotalLen - m_minScrollSliderSize) * (-m_thumbRect.top) / (double)(m_thumbRect.bottom - m_thumbRect.top - this->height())); } rect.setY(rollTop + m_scrollSize); rect.setHeight(rollLen); } else { int rollTotalLen = this->height() - 3 * m_scrollSize; int rollTop = round((double)rollTotalLen * (-m_thumbRect.top) / (double)(m_thumbRect.bottom - m_thumbRect.top)); int rollBottom = round((double)rollTotalLen * (-m_thumbRect.top + this->height() - m_scrollSize) / (double)(m_thumbRect.bottom - m_thumbRect.top)); int rollLen = rollBottom - rollTop; if (rollLen < m_minScrollSliderSize) { rollLen = m_minScrollSliderSize; rollTop = round((double)(rollTotalLen - m_minScrollSliderSize) * (-m_thumbRect.top) / (double)(m_thumbRect.bottom - m_thumbRect.top - this->height() + m_scrollSize)); } rect.setY(rollTop + m_scrollSize); rect.setHeight(rollLen); } return rect; } QRect HGImgThumb::getNullScrollPos() { assert(m_hScroll && m_vScroll); return QRect(this->width() - m_scrollSize, this->height() - m_scrollSize, m_scrollSize, m_scrollSize); } void HGImgThumb::Show() { repaint(); } void HGAPI HGImgThumb::ThreadFunc(HGThread thread, HGPointer param) { Q_UNUSED(thread); HGImgThumb *p = (HGImgThumb *)param; while (!p->m_stopThread) { QString fileName; HGBase_EnterLock(p->m_lockBack); int count = (int)p->m_backList.size(); if (count > 0) { fileName = *p->m_backList.begin(); p->m_backList.erase(p->m_backList.begin()); --count; } HGBase_LeaveLock(p->m_lockBack); if (!fileName.isEmpty()) { HGImage image = nullptr; HGImgFmt_LoadImage(getStdString(fileName).c_str(), 0, nullptr, HGBASE_IMGTYPE_RGB, HGBASE_IMGORIGIN_TOP, &image); if (nullptr != image) { HGBase_EnterLock(p->m_lockItemSize); int itemSize = p->m_itemSize; HGBase_LeaveLock(p->m_lockItemSize); QImage *img = createItemImage(image, itemSize); if (nullptr != img) { HGImageInfo imgInfo; HGBase_GetImageInfo(image, &imgInfo); HGBase_EnterLock(p->m_lockFront); int index = p->findIndex(fileName); if (-1 != index) { p->m_frontItems[index]->width = imgInfo.width; p->m_frontItems[index]->height = imgInfo.height; delete p->m_frontItems[index]->image; p->m_frontItems[index]->image = img; } HGBase_LeaveLock(p->m_lockFront); // 通知UI线程更新 emit p->updateItem(); } HGBase_DestroyImage(image); } } if (0 == count) { HGBase_WaitEvent(p->m_event); } } }