/* ToolsMenu - Add tools to the Workbench Tools menu Copyright (C) 2015, 2018 Kim Fastrup Larsen This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either ver- sion 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be use- ful, but WITHOUT ANY WARRANTY; without even the implied war- ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public Li- cense along with this program. If not, see . The author can be contacted on */ #define INTUI_V36_NAMES_ONLY #include #include #include #ifdef USE_PRAGMAS #include #endif #include "message.h" #define LINE_SPACING 1 static int max(int a, int b) { return (a > b) ? a : b; } static void button_dest(Button *button) { DisposeObject(button->gadget.GadgetRender); } static int button_cons(Button *button) { if ((button->gadget.GadgetRender = NewObject(NULL, "frameiclass", TAG_DONE)) == NULL) return 0; button->text.DrawMode = JAM1; button->text.NextText = NULL; button->gadget.Flags = GFLG_GADGHIMAGE | GFLG_GADGIMAGE; button->gadget.Activation = GACT_RELVERIFY | GACT_ENDGADGET; button->gadget.GadgetType = GTYP_BOOLGADGET | GTYP_REQGADGET; button->gadget.SelectRender = button->gadget.GadgetRender; button->gadget.GadgetText = &button->text; return 1; } static void button_layout(Button *button, struct TextAttr *font, struct DrawInfo *draw_info, UBYTE *text) { button->text.LeftEdge = draw_info->dri_Font->tf_XSize; button->text.TopEdge = draw_info->dri_Font->tf_YSize * 3 / 8; button->text.FrontPen = draw_info->dri_Pens[TEXTPEN]; button->text.ITextFont = font; button->text.IText = text; button->gadget.Width = IntuiTextLength(&button->text) + 2 * button->text.LeftEdge; button->gadget.Height = font->ta_YSize + 2 * button->text.TopEdge; SetAttrs(button->gadget.GadgetRender, IA_Width, (LONG) button->gadget.Width, IA_Height, (LONG) button->gadget.Height, TAG_DONE); } static void format_text(struct IntuiText *text, struct TextAttr *font, struct DrawInfo *draw_info, int mar_x, int mar_y, int *width, int *height) { int pad_x = draw_info->dri_Font->tf_XSize * 2; int pad_y = draw_info->dri_Font->tf_YSize * 3 / 4; int x = pad_x + mar_x; int y = pad_y + mar_y; int line_h = font->ta_YSize + LINE_SPACING; *width = 0, *height = 0; for ( ; text != NULL; text = text->NextText) { text->FrontPen = draw_info->dri_Pens[TEXTPEN]; text->DrawMode = JAM1; text->LeftEdge = x; text->TopEdge = y; text->ITextFont = font; y += line_h; *width = max(IntuiTextLength(text), *width); *height += line_h; } *width += 2 * pad_x; *height += 2 * pad_y - LINE_SPACING; } static void dispose_images(struct Image *img) { struct Image *next; while (img != NULL) { next = img->NextImage; DisposeObject(img); img = next; } } int message_cons(Message *msg) { static USHORT dither[] = { 0x5555, 0xAAAA }; struct Image *background, *outer_frame, *inner_frame; InitRequester(&msg->requester); msg->requester.ReqGadget = &msg->button.gadget; msg->requester.Flags = USEREQIMAGE | SIMPLEREQ; if ((background = NewObject(NULL, "fillrectclass", IA_APattern, dither, IA_APatSize, 1L, TAG_DONE)) == NULL) goto message_cons_failed; msg->requester.ReqImage = background; if ((outer_frame = NewObject(NULL, "frameiclass", IA_EdgesOnly, (ULONG) TRUE, TAG_DONE)) == NULL) goto message_cons_failed; background->NextImage = outer_frame; if ((inner_frame = NewObject(NULL, "frameiclass", IA_Recessed, (ULONG) TRUE, TAG_DONE)) == NULL) goto message_cons_failed; outer_frame->NextImage = inner_frame; if (!button_cons(&msg->button)) goto message_cons_failed; msg->button.gadget.NextGadget = NULL; return 1; message_cons_failed: dispose_images(msg->requester.ReqImage); return 0; } void message_layout(Message *msg, struct Window *window, struct DrawInfo *draw_info, struct IntuiText *text, UBYTE *button_text) { struct Image *background = msg->requester.ReqImage; struct Image *outer_frame = background->NextImage; struct Image *inner_frame = outer_frame->NextImage; struct TextAttr *font = window->WScreen->Font; int pad_x = draw_info->dri_Font->tf_XSize; int pad_y = draw_info->dri_Font->tf_YSize / 2; int text_w, text_h; msg->requester.ReqText = text; button_layout(&msg->button, font, draw_info, button_text); format_text(text, font, draw_info, pad_x, pad_y, &text_w, &text_h); msg->requester.Width = 2 * pad_x + text_w; msg->requester.Height = 3*pad_y - 1 + text_h + msg->button.gadget.Height; msg->button.gadget.LeftEdge = (msg->requester.Width - msg->button.gadget.Width) / 2; msg->button.gadget.TopEdge = msg->requester.Height - msg->button.gadget.Height - pad_y; msg->requester.LeftEdge = max(0, window->BorderLeft + (window->Width - window->BorderLeft - window->BorderRight - msg->requester.Width) / 2); msg->requester.TopEdge = max(0, window->BorderTop + (window->Height - window->BorderTop - window->BorderBottom - msg->requester.Height) / 2); SetAttrs(inner_frame, IA_Left, (LONG) pad_x, IA_Top, (LONG) pad_y, IA_Width, (LONG) text_w, IA_Height, (LONG) text_h, TAG_DONE); SetAttrs(outer_frame, IA_Width, (LONG) msg->requester.Width, IA_Height, (LONG) msg->requester.Height, TAG_DONE); SetAttrs(background, IA_Width, (LONG) msg->requester.Width, IA_Height, (LONG) msg->requester.Height, IA_FGPen, (ULONG) draw_info->dri_Pens[SHINEPEN], TAG_DONE); } void message_dest(Message *msg) { button_dest(&msg->button); dispose_images(msg->requester.ReqImage); }