ToolsMenu/message.c

195 行
6.1 KiB
C
可执行文件

/*
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
<http://www.gnu.org/licenses/>.
The author can be contacted on <kimflarsen@hotmail.com>
*/
#define INTUI_V36_NAMES_ONLY
#include <intuition/imageclass.h>
#include <intuition/intuition.h>
#include <clib/intuition_protos.h>
#ifdef USE_PRAGMAS
#include <proto/intuition.h>
#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);
}