Add tools to the Workbench Tools menu
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

message.c 6.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. /*
  2. ToolsMenu - Add tools to the Workbench Tools menu
  3. Copyright (C) 2015, 2018 Kim Fastrup Larsen
  4. This program is free software: you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation, either ver-
  7. sion 3 of the License, or (at your option) any later version.
  8. This program is distributed in the hope that it will be use-
  9. ful, but WITHOUT ANY WARRANTY; without even the implied war-
  10. ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. See the GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public Li-
  13. cense along with this program. If not, see
  14. <http://www.gnu.org/licenses/>.
  15. The author can be contacted on <kimflarsen@hotmail.com>
  16. */
  17. #define INTUI_V36_NAMES_ONLY
  18. #include <intuition/imageclass.h>
  19. #include <intuition/intuition.h>
  20. #include <clib/intuition_protos.h>
  21. #ifdef USE_PRAGMAS
  22. #include <proto/intuition.h>
  23. #endif
  24. #include "message.h"
  25. #define LINE_SPACING 1
  26. static int max(int a, int b)
  27. {
  28. return (a > b) ? a : b;
  29. }
  30. static void button_dest(Button *button)
  31. {
  32. DisposeObject(button->gadget.GadgetRender);
  33. }
  34. static int button_cons(Button *button)
  35. {
  36. if ((button->gadget.GadgetRender = NewObject(NULL, "frameiclass",
  37. TAG_DONE)) == NULL)
  38. return 0;
  39. button->text.DrawMode = JAM1;
  40. button->text.NextText = NULL;
  41. button->gadget.Flags = GFLG_GADGHIMAGE | GFLG_GADGIMAGE;
  42. button->gadget.Activation = GACT_RELVERIFY | GACT_ENDGADGET;
  43. button->gadget.GadgetType = GTYP_BOOLGADGET | GTYP_REQGADGET;
  44. button->gadget.SelectRender = button->gadget.GadgetRender;
  45. button->gadget.GadgetText = &button->text;
  46. return 1;
  47. }
  48. static void button_layout(Button *button, struct TextAttr *font,
  49. struct DrawInfo *draw_info, UBYTE *text)
  50. {
  51. button->text.LeftEdge = draw_info->dri_Font->tf_XSize;
  52. button->text.TopEdge = draw_info->dri_Font->tf_YSize * 3 / 8;
  53. button->text.FrontPen = draw_info->dri_Pens[TEXTPEN];
  54. button->text.ITextFont = font;
  55. button->text.IText = text;
  56. button->gadget.Width = IntuiTextLength(&button->text) + 2 *
  57. button->text.LeftEdge;
  58. button->gadget.Height = font->ta_YSize + 2 * button->text.TopEdge;
  59. SetAttrs(button->gadget.GadgetRender,
  60. IA_Width, (LONG) button->gadget.Width,
  61. IA_Height, (LONG) button->gadget.Height,
  62. TAG_DONE);
  63. }
  64. static void format_text(struct IntuiText *text, struct TextAttr *font,
  65. struct DrawInfo *draw_info, int mar_x, int mar_y, int *width, int *height)
  66. {
  67. int pad_x = draw_info->dri_Font->tf_XSize * 2;
  68. int pad_y = draw_info->dri_Font->tf_YSize * 3 / 4;
  69. int x = pad_x + mar_x;
  70. int y = pad_y + mar_y;
  71. int line_h = font->ta_YSize + LINE_SPACING;
  72. *width = 0, *height = 0;
  73. for ( ; text != NULL; text = text->NextText) {
  74. text->FrontPen = draw_info->dri_Pens[TEXTPEN];
  75. text->DrawMode = JAM1;
  76. text->LeftEdge = x;
  77. text->TopEdge = y;
  78. text->ITextFont = font;
  79. y += line_h;
  80. *width = max(IntuiTextLength(text), *width);
  81. *height += line_h;
  82. }
  83. *width += 2 * pad_x;
  84. *height += 2 * pad_y - LINE_SPACING;
  85. }
  86. static void dispose_images(struct Image *img)
  87. {
  88. struct Image *next;
  89. while (img != NULL) {
  90. next = img->NextImage;
  91. DisposeObject(img);
  92. img = next;
  93. }
  94. }
  95. int message_cons(Message *msg)
  96. {
  97. static USHORT dither[] = { 0x5555, 0xAAAA };
  98. struct Image *background, *outer_frame, *inner_frame;
  99. InitRequester(&msg->requester);
  100. msg->requester.ReqGadget = &msg->button.gadget;
  101. msg->requester.Flags = USEREQIMAGE | SIMPLEREQ;
  102. if ((background = NewObject(NULL, "fillrectclass",
  103. IA_APattern, dither,
  104. IA_APatSize, 1L,
  105. TAG_DONE)) == NULL)
  106. goto message_cons_failed;
  107. msg->requester.ReqImage = background;
  108. if ((outer_frame = NewObject(NULL, "frameiclass",
  109. IA_EdgesOnly, (ULONG) TRUE,
  110. TAG_DONE)) == NULL)
  111. goto message_cons_failed;
  112. background->NextImage = outer_frame;
  113. if ((inner_frame = NewObject(NULL, "frameiclass",
  114. IA_Recessed, (ULONG) TRUE,
  115. TAG_DONE)) == NULL)
  116. goto message_cons_failed;
  117. outer_frame->NextImage = inner_frame;
  118. if (!button_cons(&msg->button))
  119. goto message_cons_failed;
  120. msg->button.gadget.NextGadget = NULL;
  121. return 1;
  122. message_cons_failed:
  123. dispose_images(msg->requester.ReqImage);
  124. return 0;
  125. }
  126. void message_layout(Message *msg, struct Window *window,
  127. struct DrawInfo *draw_info, struct IntuiText *text, UBYTE *button_text)
  128. {
  129. struct Image *background = msg->requester.ReqImage;
  130. struct Image *outer_frame = background->NextImage;
  131. struct Image *inner_frame = outer_frame->NextImage;
  132. struct TextAttr *font = window->WScreen->Font;
  133. int pad_x = draw_info->dri_Font->tf_XSize;
  134. int pad_y = draw_info->dri_Font->tf_YSize / 2;
  135. int text_w, text_h;
  136. msg->requester.ReqText = text;
  137. button_layout(&msg->button, font, draw_info, button_text);
  138. format_text(text, font, draw_info, pad_x, pad_y, &text_w, &text_h);
  139. msg->requester.Width = 2 * pad_x + text_w;
  140. msg->requester.Height = 3*pad_y - 1 + text_h + msg->button.gadget.Height;
  141. msg->button.gadget.LeftEdge = (msg->requester.Width -
  142. msg->button.gadget.Width) / 2;
  143. msg->button.gadget.TopEdge = msg->requester.Height -
  144. msg->button.gadget.Height - pad_y;
  145. msg->requester.LeftEdge = max(0, window->BorderLeft + (window->Width -
  146. window->BorderLeft - window->BorderRight - msg->requester.Width) / 2);
  147. msg->requester.TopEdge = max(0, window->BorderTop + (window->Height -
  148. window->BorderTop - window->BorderBottom - msg->requester.Height) / 2);
  149. SetAttrs(inner_frame,
  150. IA_Left, (LONG) pad_x,
  151. IA_Top, (LONG) pad_y,
  152. IA_Width, (LONG) text_w,
  153. IA_Height, (LONG) text_h,
  154. TAG_DONE);
  155. SetAttrs(outer_frame,
  156. IA_Width, (LONG) msg->requester.Width,
  157. IA_Height, (LONG) msg->requester.Height,
  158. TAG_DONE);
  159. SetAttrs(background,
  160. IA_Width, (LONG) msg->requester.Width,
  161. IA_Height, (LONG) msg->requester.Height,
  162. IA_FGPen, (ULONG) draw_info->dri_Pens[SHINEPEN],
  163. TAG_DONE);
  164. }
  165. void message_dest(Message *msg)
  166. {
  167. button_dest(&msg->button);
  168. dispose_images(msg->requester.ReqImage);
  169. }