summaryrefslogtreecommitdiff
path: root/iup/src/win/iupwin_label.c
diff options
context:
space:
mode:
Diffstat (limited to 'iup/src/win/iupwin_label.c')
-rwxr-xr-xiup/src/win/iupwin_label.c339
1 files changed, 339 insertions, 0 deletions
diff --git a/iup/src/win/iupwin_label.c b/iup/src/win/iupwin_label.c
new file mode 100755
index 0000000..d5a1f53
--- /dev/null
+++ b/iup/src/win/iupwin_label.c
@@ -0,0 +1,339 @@
+/** \file
+ * \brief Label Control
+ *
+ * See Copyright Notice in "iup.h"
+ */
+
+#include <windows.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <memory.h>
+#include <stdarg.h>
+
+#include "iup.h"
+#include "iupcbs.h"
+
+#include "iup_object.h"
+#include "iup_attrib.h"
+#include "iup_str.h"
+#include "iup_label.h"
+#include "iup_drv.h"
+#include "iup_drvfont.h"
+#include "iup_image.h"
+
+#include "iupwin_drv.h"
+#include "iupwin_handle.h"
+#include "iupwin_draw.h"
+
+
+static void winLabelDrawImage(Ihandle* ih, HDC hDC, int rect_width, int rect_height)
+{
+ int xpad = ih->data->horiz_padding,
+ ypad = ih->data->vert_padding;
+ int x, y, width, height, bpp;
+ HBITMAP hBitmap, hMask = NULL;
+ char *name;
+ int make_inactive = 0;
+
+ if (iupdrvIsActive(ih))
+ name = iupAttribGet(ih, "IMAGE");
+ else
+ {
+ name = iupAttribGet(ih, "IMINACTIVE");
+ if (!name)
+ {
+ name = iupAttribGet(ih, "IMAGE");
+ make_inactive = 1;
+ }
+ }
+
+ hBitmap = iupImageGetImage(name, ih, make_inactive);
+ if (!hBitmap)
+ return;
+
+ /* must use this info, since image can be a driver image loaded from resources */
+ iupdrvImageGetInfo(hBitmap, &width, &height, &bpp);
+
+ if (ih->data->horiz_alignment == IUP_ALIGN_ARIGHT)
+ x = rect_width - (width + 2*xpad);
+ else if (ih->data->horiz_alignment == IUP_ALIGN_ACENTER)
+ x = (rect_width - (width + 2*xpad))/2;
+ else /* ALEFT */
+ x = 0;
+
+ if (ih->data->vert_alignment == IUP_ALIGN_ABOTTOM)
+ y = rect_height - (height + 2*ypad);
+ else if (ih->data->vert_alignment == IUP_ALIGN_ATOP)
+ y = 0;
+ else /* ACENTER */
+ y = (rect_height - (height + 2*ypad))/2;
+
+ x += xpad;
+ y += ypad;
+
+ if (bpp == 8)
+ hMask = iupdrvImageCreateMask(IupGetHandle(name));
+
+ iupwinDrawBitmap(hDC, hBitmap, hMask, x, y, width, height, bpp);
+
+ if (hMask)
+ DeleteObject(hMask);
+}
+
+static void winLabelDrawText(Ihandle* ih, HDC hDC, int rect_width, int rect_height)
+{
+ int xpad = ih->data->horiz_padding,
+ ypad = ih->data->vert_padding;
+ int x, y, width, height, style;
+ HFONT hFont = (HFONT)iupwinGetHFontAttrib(ih);
+ COLORREF fgcolor;
+
+ char* title = iupdrvBaseGetTitleAttrib(ih);
+ char* str = iupStrProcessMnemonic(title, NULL, 0); /* remove & */
+ iupdrvFontGetMultiLineStringSize(ih, str, &width, &height);
+ if (str && str!=title) free(str);
+
+ if (ih->data->horiz_alignment == IUP_ALIGN_ARIGHT)
+ style = DT_RIGHT;
+ else if (ih->data->horiz_alignment == IUP_ALIGN_ACENTER)
+ style = DT_CENTER;
+ else /* ALEFT */
+ style = DT_LEFT;
+
+ if (ih->data->vert_alignment == IUP_ALIGN_ABOTTOM)
+ y = rect_height - (height + 2*ypad);
+ else if (ih->data->vert_alignment == IUP_ALIGN_ATOP)
+ y = 0;
+ else /* ACENTER */
+ y = (rect_height - (height + 2*ypad))/2;
+
+ /* let DrawText do the horizontal alignment */
+ x = xpad;
+ width = rect_width - 2*xpad;
+ y += ypad;
+
+ if (iupdrvIsActive(ih))
+ fgcolor = ih->data->fgcolor;
+ else
+ fgcolor = GetSysColor(COLOR_GRAYTEXT);
+
+ /* WORDWRAP and ELLIPSIS */
+ style |= ih->data->text_style;
+
+ iupwinDrawText(hDC, title, x, y, width, height, hFont, fgcolor, style);
+}
+
+static void winLabelDrawItem(Ihandle* ih, DRAWITEMSTRUCT *drawitem)
+{
+ HDC hDC;
+ iupwinBitmapDC bmpDC;
+ int width, height;
+
+ if (!(drawitem->itemAction & ODA_DRAWENTIRE))
+ return;
+
+ width = drawitem->rcItem.right - drawitem->rcItem.left;
+ height = drawitem->rcItem.bottom - drawitem->rcItem.top;
+
+ hDC = iupwinDrawCreateBitmapDC(&bmpDC, drawitem->hDC, width, height);
+
+ iupwinDrawParentBackground(ih, hDC, &drawitem->rcItem);
+
+ if (ih->data->type == IUP_LABEL_IMAGE)
+ winLabelDrawImage(ih, hDC, width, height);
+ else
+ winLabelDrawText(ih, hDC, width, height);
+
+ iupwinDrawDestroyBitmapDC(&bmpDC);
+}
+
+/************************************************************************************************/
+
+static int winLabelSetAlignmentAttrib(Ihandle* ih, const char* value)
+{
+ if (ih->data->type != IUP_LABEL_SEP_HORIZ && ih->data->type != IUP_LABEL_SEP_VERT)
+ {
+ char value1[30] = "", value2[30] = "";
+
+ iupStrToStrStr(value, value1, value2, ':');
+
+ if (iupStrEqualNoCase(value1, "ARIGHT"))
+ ih->data->horiz_alignment = IUP_ALIGN_ARIGHT;
+ else if (iupStrEqualNoCase(value1, "ACENTER"))
+ ih->data->horiz_alignment = IUP_ALIGN_ACENTER;
+ else /* "ALEFT" */
+ ih->data->horiz_alignment = IUP_ALIGN_ALEFT;
+
+ if (iupStrEqualNoCase(value2, "ABOTTOM"))
+ ih->data->vert_alignment = IUP_ALIGN_ABOTTOM;
+ else if (iupStrEqualNoCase(value2, "ACENTER"))
+ ih->data->vert_alignment = IUP_ALIGN_ACENTER;
+ else /* "ATOP" */
+ ih->data->vert_alignment = IUP_ALIGN_ATOP;
+
+ iupdrvDisplayRedraw(ih);
+ }
+ return 0;
+}
+
+static char* winLabelGetAlignmentAttrib(Ihandle *ih)
+{
+ if (ih->data->type != IUP_LABEL_SEP_HORIZ && ih->data->type != IUP_LABEL_SEP_VERT)
+ {
+ char* horiz_align2str[3] = {"ALEFT", "ACENTER", "ARIGHT"};
+ char* vert_align2str[3] = {"ATOP", "ACENTER", "ABOTTOM"};
+ char *str = iupStrGetMemory(50);
+ sprintf(str, "%s:%s", horiz_align2str[ih->data->horiz_alignment], vert_align2str[ih->data->vert_alignment]);
+ return str;
+ }
+ else
+ return NULL;
+}
+
+static int winLabelSetPaddingAttrib(Ihandle* ih, const char* value)
+{
+ iupStrToIntInt(value, &ih->data->horiz_padding, &ih->data->vert_padding, 'x');
+
+ if (ih->handle && ih->data->type != IUP_LABEL_SEP_HORIZ && ih->data->type != IUP_LABEL_SEP_VERT)
+ iupdrvDisplayRedraw(ih);
+
+ return 0;
+}
+
+static int winLabelSetWordWrapAttrib(Ihandle* ih, const char* value)
+{
+ if (ih->data->type == IUP_LABEL_TEXT)
+ {
+ if (iupStrBoolean(value))
+ ih->data->text_style |= DT_WORDBREAK;
+ else
+ ih->data->text_style &= ~DT_WORDBREAK;
+
+ iupdrvDisplayRedraw(ih);
+ }
+
+ return 1;
+}
+
+static int winLabelSetEllipsisAttrib(Ihandle* ih, const char* value)
+{
+ if (ih->data->type == IUP_LABEL_TEXT)
+ {
+ if (iupStrBoolean(value))
+ ih->data->text_style |= DT_END_ELLIPSIS;
+ else
+ ih->data->text_style &= ~DT_END_ELLIPSIS;
+
+ iupdrvDisplayRedraw(ih);
+ }
+
+ return 1;
+}
+
+static int winLabelSetFgColorAttrib(Ihandle* ih, const char* value)
+{
+ if (ih->data->type != IUP_LABEL_SEP_HORIZ && ih->data->type != IUP_LABEL_SEP_VERT)
+ {
+ unsigned char r, g, b;
+ if (iupStrToRGB(value, &r, &g, &b))
+ {
+ ih->data->fgcolor = RGB(r,g,b);
+ iupdrvDisplayRedraw(ih);
+ }
+ }
+ return 1;
+}
+
+static int winLabelProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *result)
+{
+ switch (msg)
+ {
+ case WM_NCCALCSIZE:
+ {
+ if (wp == TRUE)
+ {
+ *result = WVR_HREDRAW|WVR_VREDRAW;
+ return 1;
+ }
+ }
+ }
+
+ return iupwinBaseProc(ih, msg, wp, lp, result);
+}
+
+static int winLabelMapMethod(Ihandle* ih)
+{
+ char* value;
+ DWORD dwStyle = WS_CHILD |
+ SS_NOTIFY; /* SS_NOTIFY is necessary because of the base messages */
+
+ if (!ih->parent)
+ return IUP_ERROR;
+
+ value = iupAttribGet(ih, "SEPARATOR");
+ if (value)
+ {
+ if (iupStrEqualNoCase(value, "HORIZONTAL"))
+ {
+ ih->data->type = IUP_LABEL_SEP_HORIZ;
+ dwStyle |= SS_ETCHEDHORZ;
+ }
+ else /* "VERTICAL" */
+ {
+ ih->data->type = IUP_LABEL_SEP_VERT;
+ dwStyle |= SS_ETCHEDVERT;
+ }
+ }
+ else
+ {
+ /* The lack for good alignment support in STATIC control forces IUP to draw its own label,
+ but uses the Windows functions to draw text and images in native format. */
+ dwStyle |= SS_OWNERDRAW;
+
+ value = iupAttribGet(ih, "IMAGE");
+ if (value)
+ ih->data->type = IUP_LABEL_IMAGE;
+ else
+ ih->data->type = IUP_LABEL_TEXT;
+ }
+
+ if (!iupwinCreateWindowEx(ih, "STATIC", 0, dwStyle))
+ return IUP_ERROR;
+
+ if (ih->data->type != IUP_LABEL_SEP_HORIZ && ih->data->type != IUP_LABEL_SEP_VERT)
+ {
+ /* replace the WinProc to handle other messages */
+ IupSetCallback(ih, "_IUPWIN_CTRLPROC_CB", (Icallback)winLabelProc);
+
+ IupSetCallback(ih, "_IUPWIN_DRAWITEM_CB", (Icallback)winLabelDrawItem);
+ }
+
+ return IUP_NOERROR;
+}
+
+void iupdrvLabelInitClass(Iclass* ic)
+{
+ /* Driver Dependent Class functions */
+ ic->Map = winLabelMapMethod;
+
+ /* Driver Dependent Attribute functions */
+
+ /* Visual */
+ /* the most important use of this is to provide the correct background for images */
+ iupClassRegisterAttribute(ic, "BGCOLOR", iupBaseNativeParentGetBgColorAttrib, NULL, IUPAF_SAMEASSYSTEM, "DLGBGCOLOR", IUPAF_DEFAULT);
+
+ /* Special */
+ iupClassRegisterAttribute(ic, "FGCOLOR", NULL, winLabelSetFgColorAttrib, "DLGFGCOLOR", NULL, IUPAF_NOT_MAPPED); /* force new default value */
+ iupClassRegisterAttribute(ic, "TITLE", iupdrvBaseGetTitleAttrib, iupdrvBaseSetTitleAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
+
+ /* IupLabel only */
+ iupClassRegisterAttribute(ic, "ALIGNMENT", winLabelGetAlignmentAttrib, winLabelSetAlignmentAttrib, IUPAF_SAMEASSYSTEM, "ALEFT:ACENTER", IUPAF_NO_INHERIT);
+ iupClassRegisterAttribute(ic, "IMAGE", NULL, NULL, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
+ iupClassRegisterAttribute(ic, "PADDING", iupLabelGetPaddingAttrib, winLabelSetPaddingAttrib, IUPAF_SAMEASSYSTEM, "0x0", IUPAF_NOT_MAPPED);
+
+ /* IupLabel Windows and GTK only */
+ iupClassRegisterAttribute(ic, "WORDWRAP", NULL, winLabelSetWordWrapAttrib, NULL, NULL, IUPAF_DEFAULT);
+ iupClassRegisterAttribute(ic, "ELLIPSIS", NULL, winLabelSetEllipsisAttrib, NULL, NULL, IUPAF_DEFAULT);
+}