diff options
author | Pixel <pixel@nobis-crew.org> | 2009-11-04 11:56:41 -0800 |
---|---|---|
committer | Pixel <pixel@nobis-crew.org> | 2009-11-04 11:59:33 -0800 |
commit | d577d991b97ae2b5ee1af23641bcffc3f83af5b2 (patch) | |
tree | 590639d50205d1bcfaff2a7d2dc6ebf3f373c7ed /iup/src/win/iupwin_label.c |
Initial import. Contains the im, cd and iup librairies, and a "working" Makefile for them under linux.
Diffstat (limited to 'iup/src/win/iupwin_label.c')
-rwxr-xr-x | iup/src/win/iupwin_label.c | 339 |
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); +} |