#include <utils/common/UtilExceptions.h>
#include <fxkeys.h>
#include "MFXListIconItem.h"
#include "MFXListIcon.h"
#define SIDE_SPACING 6
#define ICON_SPACING 4
#define LINE_SPACING 4
#define ICON_SIZE 16
FXIMPLEMENT(MFXListIconItem, FXObject, nullptr, 0)
MFXListIconItem::MFXListIconItem(const FXString& text, FXIcon* ic, FXColor backGroundColor, void* ptr):
label(text),
icon(ic),
data(ptr),
myBackGroundColor(backGroundColor) {
}
MFXListIconItem::~MFXListIconItem() {
if (state & ICONOWNED) {
delete icon;
}
icon = (FXIcon*) - 1L;
}
void
MFXListIconItem::setFocus(FXbool focus) {
if (focus) {
state |= FOCUS;
} else {
state &= ~(FXuint)FOCUS;
}
}
FXbool
MFXListIconItem::hasFocus() const {
return (state & FOCUS) != 0;
}
void
MFXListIconItem::setSelected(FXbool selected) {
if (selected) {
state |= SELECTED;
} else {
state &= ~SELECTED;
}
}
FXbool
MFXListIconItem::isSelected() const {
return (state & SELECTED) != 0;
}
void
MFXListIconItem::setEnabled(FXbool enabled) {
if (enabled) {
state &= ~DISABLED;
} else {
state |= DISABLED;
}
}
FXbool
MFXListIconItem::isEnabled() const {
return (state & DISABLED) == 0;
}
void
MFXListIconItem::setDraggable(FXbool draggable) {
if (draggable) {
state |= DRAGGABLE;
} else {
state &= ~DRAGGABLE;
}
}
FXbool
MFXListIconItem::isDraggable() const {
return (state & DRAGGABLE) != 0;
}
void
MFXListIconItem::setText(const FXString& txt) {
label = txt;
}
const FXString&
MFXListIconItem::getText() const {
return label;
}
FXIcon*
MFXListIconItem::getIcon() const {
return icon;
}
void
MFXListIconItem::create() {
if (icon) {
icon->create();
}
}
void
MFXListIconItem::destroy() {
if ((state & ICONOWNED) && icon) {
icon->destroy();
}
}
void
MFXListIconItem::detach() {
if (icon) {
icon->detach();
}
}
FXint
MFXListIconItem::getWidth(const MFXListIcon* list) const {
FXFont* font = list->getFont();
FXint w = 0;
if (icon) {
w = icon->getWidth();
}
if (!label.empty()) {
if (w) {
w += ICON_SPACING;
}
w += font->getTextWidth(label.text(), label.length());
}
return SIDE_SPACING + w;
}
FXint
MFXListIconItem::getHeight(const MFXListIcon* list) const {
FXFont* font = list->getFont();
FXint th = 0, ih = 0;
if (icon) {
ih = icon->getHeight();
}
if (!label.empty()) {
th = font->getFontHeight();
}
return LINE_SPACING + FXMAX(th, ih);
}
const FXColor&
MFXListIconItem::getBackGroundColor() const {
return myBackGroundColor;
}
MFXListIconItem::MFXListIconItem() {}
void
MFXListIconItem::draw(const MFXListIcon* list, FXDC& dc, FXint xx, FXint yy, FXint ww, FXint hh) {
FXFont* font = list->getFont();
FXint ih = icon ? ICON_SIZE : 0;
FXint th = 0;
if (!label.empty()) {
th = font->getFontHeight();
}
if (isSelected()) {
dc.setForeground(list->getSelBackColor());
} else {
dc.setForeground(myBackGroundColor);
}
dc.fillRectangle(xx, yy, ww, hh);
if (hasFocus()) {
dc.drawFocusRectangle(xx + 1, yy + 1, ww - 2, hh - 2);
}
xx += SIDE_SPACING / 2;
if (icon) {
dc.drawIcon(icon, xx, yy + (hh - ih) / 2);
}
if (icon) {
xx += ICON_SPACING + ICON_SIZE;
}
if (!label.empty()) {
dc.setFont(font);
if (!isEnabled()) {
dc.setForeground(makeShadowColor(list->getBackColor()));
} else if (isSelected()) {
dc.setForeground(list->getSelTextColor());
} else {
dc.setForeground(list->getTextColor());
}
dc.drawText(xx, yy + (hh - th) / 2 + font->getFontAscent(), label);
}
}
FXint
MFXListIconItem::hitItem(const MFXListIcon* list, FXint xx, FXint yy) const {
FXint iw = 0, ih = 0, tw = 0, th = 0, ix, iy, tx, ty, h;
FXFont* font = list->getFont();
if (icon) {
iw = icon->getWidth();
ih = icon->getHeight();
}
if (!label.empty()) {
tw = 4 + font->getTextWidth(label.text(), label.length());
th = 4 + font->getFontHeight();
}
h = LINE_SPACING + FXMAX(th, ih);
ix = SIDE_SPACING / 2;
tx = SIDE_SPACING / 2;
if (iw) {
tx += iw + ICON_SPACING;
}
iy = (h - ih) / 2;
ty = (h - th) / 2;
if (ix <= xx && iy <= yy && xx < ix + iw && yy < iy + ih) {
return 1;
}
if (tx <= xx && ty <= yy && xx < tx + tw && yy < ty + th) {
return 2;
}
return 0;
}