Aros/開發者/文件/庫/GadTools
- V34 - OS1.3x Gadtools不存在,但gadtools13.library存在
- V36 - OS2.0x 首次引入
- V37 - OS2.04 NewLook渲染方案
- V39 - OS3.0x 添加了NewLook選單 - 添加了GT_GetGadgetAttrs() -
- V40 - OS3.1x 修復
在AmigaOS™ 2.0之前,沒有統一的介面設計標準——應用程式開發者必須編寫自己的物件(按鈕、請求器和選單),Intuition提供最小的支援。AmigaOS™ 2.0帶來了gadtools.library,它提供了標準的小部件集,以及介面樣式指南,解釋瞭如何佈局應用程式以確保使用者的一致性。
Gadtools是一個已棄用的介面,因為它有限制性(在某些情況下確實有其優勢)。嘗試僅使用BOOPSI gadgets,這將導致我們稱為Zune的MUI版本。BOOPSI是MUI、bgui等的基礎。
許多GadTools函式使用TagItem陣列或標籤列表在函式介面之間傳遞資訊。這些基於標籤的函式有兩種型別,一種採用指向TagItem陣列的指標,另一種直接在函式呼叫中採用可變數量的TagItem引數。通常,第二種形式(通常稱為varargs形式,因為呼叫採用可變數量的引數)是為了方便而提供的,並在內部轉換為第一種形式。
所有Gadtools標籤都以“GT”開頭。通常,它們還具有表示相關Gadgets型別的兩個字母的助記符。例如,滑塊gadgets識別諸如“GTSL_Level”之類的標籤。
對於大多數Gadgets,NewGadget結構用於指定其公共屬性。特定Gadgets型別的唯一屬性被指定為傳送到CreateGadget()函式的標籤。
各種GadTools Gadgets型別需要某些類別的IDCMP訊息才能工作。應用程式在視窗開啟時或稍後使用ModifyIDCMP()指定這些IDCMP類。每種GadTools Gadgets都需要這些IDCMP類中的一種或多種。
IDCMP_GADGETUP, IDCMP_GADGETDOWN, IDCMP_MOUSEMOVE, IDCMP_MOUSEBUTTONS and IDCMP_INTUITICKS.
關閉視窗後,必須釋放使用CreateGadget()分配的Gadgets。
視窗座標到GadTools Gadgets座標的直接轉換。GaDTools使用者介面易於使用,但Gadgets座標除外。還需要一個基於這些座標的繪製矩形函式來校準我的繪圖區域和擦除矩形座標。
對GadTools Gadgets允許使用一組嚴格的函式和操作。
切勿選擇性或強制重新整理Gadgets。唯一應執行的Gadgets重新整理是在視窗使用GadTools Gadgets附加後開啟後進行的初始GT_RefreshWindow()。在視窗開啟後也可以透過呼叫AddGlist()和RefreshGlist(),然後呼叫GT_RefreshWindow()來新增Gadgets。這些重新整理函式不應該在任何其他時間呼叫。
GadTools Gadgets不得相互重疊,不得與其他Gadgets或其他元素重疊。這樣做以修改Gadgets的外觀不受支援。
GadTools Gadgets不得從視窗中選擇性地新增或刪除。這與每次呼叫CreateGadget()產生的Intuition Gadgets數量以及重新整理限制有關。
切勿使用OnGadget()或OffGadget()或直接修改GFLG_DISABLED Flags位。停用或啟用Gadgets的唯一批准方法是使用GT_SetGadgetAttrs()和GA_Disabled標籤。不支援GA_Disabled的那些Gadgets型別可能無法停用。
應用程式絕不應寫入Gadget結構或任何需要它的結構的任何欄位,除非它們是顯式的程式設計師欄位(例如GadgetID和UserData),或者它們是保證有意義的。
(LeftEdge, TopEdge, Width, Height, Flags).
有時,程式會被特別邀請讀取某個欄位,例如StringInfo->Buffer欄位。
GadTools Gadgets不得設定為相對大小或相對定位。這意味著不得指定Gadgets標誌GFLG_RELWIDTH、GFLG_RELHEIGHT、GFLG_RELBOTTOM和GFLG_RELRIGHT。Gadgets的啟用型別不得修改(例如,將GACT_IMMEDIATE更改為GACT_RELVERIFY)。
| Gadgets型別 | 描述或示例用法 |
|---|---|
| 按鈕 | 熟悉的動作gadgets,例如“確定”或“取消”。 |
| 字串 | 用於文字輸入。 |
| 整數 | 用於數字輸入。 |
| 複選框 | 用於開關專案。 |
| 互斥 | 單選按鈕,在多個選項中選擇一個。 |
| 迴圈 | 多選,從少量選項中選擇一個。 |
| 滑塊 | 指示範圍內的級別。 |
| 捲軸 | 指示列表或區域中的位置。 |
| 列表檢視 | 文字的滾動列表。 |
| 調色盤 | 顏色選擇。 |
| 文字顯示 | 只讀文字。 |
| 數字顯示 | 只讀數字。 |
建立http://thomas-rapp.homepage.t-online.de/examples/gadtools.c
要更改Gadgets顯示後標誌和主體變數,程式可以呼叫Intuition的NewModifyProp()。
void NewModifyProp( struct Gadget *gadget, struct Window *window, struct Requester *requester,
unsigned long flags, unsigned long horizPot, unsigned long vertPot,
unsigned long horizBody, unsigned long vertBody, long numGad );
Gadgets的內部狀態將重新計算,並且影像將重新顯示以顯示新狀態。當numGads(在上面的原型中)設定為全1時,NewModifyProp()將僅更新已更改的部分,這比刪除Gadgets、更改值、新增Gadgets並重新整理要快得多。
每種GadTools Gadgets都需要這些IDCMP類中的一種或多種:IDCMP_GADGETUP、IDCMP_GADGETDOWN、IDCMP_MOUSEMOVE、IDCMP_MOUSEBUTTONS和IDCMP_INTUITICKS。
使用Gadgets的程式始終需要關於視窗重新整理事件的通知。即使應用程式沒有執行自己的渲染,它也可能不使用WFLG_NOCAREREFRESH視窗標誌,並且必須始終設定IDCMP_REFRESHWINDOW。
Gadgets的屬性在建立Gadgets時設定。其中一些屬性可以透過使用GT_SetGadgetAttrs()函式稍後更改。
void GT_SetGadgetAttrs (struct Gadget *gad, struct Window *win,
struct Requester *req, Tag tag1, ... )
void GT_SetGadgetAttrsA(struct Gadget *gad, struct Window *win,
struct Requester *req, struct TagItem *taglist)
按鈕gadgets(BUTTON_KIND)可能是最簡單的GadTools Gadgets。
文字輸入(STRING_KIND)和數字輸入(INTEGER_KIND)gadgets是相當典型的Intuition字串gadgets。
迴圈gadgets(CYCLE_KIND)允許使用者從多個選項中準確選擇一個。
GadTools Gadgets和選單需要有關其將顯示在其上的螢幕的資訊。在建立任何GadTools Gadgets或選單之前,程式必須使用GetVisualInfo()呼叫獲取此資訊。
選單。GadTools完全支援Intuition的NewLook選單。可以透過提供以下內容將NewLook選單新增到應用程式中:
{WA_NewLookMenus, TRUE} tag to OpenWindowTags(),
並提供以下內容:
{GTMN_NewLookMenus, TRUE} tag to LayoutMenus().
這兩個標籤將為您的應用程式提供 NewLook 選單。使用者可以透過調色盤首選項編輯器控制用於渲染這些選單的畫筆。
您現在可以在選單的右側放置任意命令字串,Amiga 鍵等效項通常位於此處。要執行此操作,請將 NewMenu.nm_CommKey 欄位指向該字串(例如,“Shift-Alt-F1”),並在 NewMenu.nm_Flags 中設定新的 NM_COMMANDSTRING 標誌。
GT_GetGadgetAttrs()。GadTools 現在有一個 GT_GetGadgetAttrsA() 函式,它根據標籤列表中選擇的屬性檢索指定元件的屬性。對於標籤列表中的每個條目,ti_Tag 標識屬性,而 ti_Data 是指向您希望將結果儲存在其中的長整型變數的指標。
LONG top = 0;
LONG selected = 0;
LONG result;
result = GT_GetGadgetAttrs(listview_gad, win, NULL,
GTLV_Top, &top,
GTLV_Selected, &selected,
TAG_DONE);
if (result != 2)
{
printf( "Something's wrong!" );
}
大多數常規 Intuition 字串元件預設為 FALSE
列表檢視。GadTools 列表檢視
滾動列表區域底部的顯示框消失。它不再在顯示框中顯示選定的專案,而是將選定的專案在滾動列表中突出顯示。這樣做是為了為列表檢視準備多選支援。多選需要突出顯示方案,因為顯示框將無法工作。移除顯示框會對列表檢視的大小造成輕微影響。
GTLV_CallBack。此標籤允許為 Gadtools 提供回撥鉤子以進行列表檢視處理。目前,該鉤子僅在渲染單個專案時被呼叫。每次 GadTools 希望渲染列表檢視中的專案時,它都會呼叫回撥函式,該函式可以執行自定義渲染。這使得 GadTools 列表檢視可以用於滾動複雜專案,例如圖形和影像。
列表檢視現在可以使用 {GA_Disabled, TRUE} 停用。
調色盤。GadTools 調色盤元件不再顯示一個填充選定顏色的框。選定顏色現在由在主調色盤區域中繪製在顏色方塊周圍的框表示。此更改會略微影響調色盤元件的大小。
另一個可能影響調色盤元件大小的更改是顏色方塊的更智慧佈局。現在嘗試根據從圖形資料庫中獲取的縱橫比資訊,使顏色方塊儘可能地正方形。螢幕上會放置儘可能多的顏色方塊,直到它們變得太小,在這種情況下,上面的顏色將被丟棄。GTPA_ColorTable 標籤是在稀疏顏色表的支援下新增的。它允許您定義任意畫筆以用於填充調色盤元件的顏色方塊。
GTPA_NumColors 標籤允許您定義在調色盤元件中顯示的顏色確切數量。在 V37 下,GTPA_Depth 標籤發揮著相同的作用。GTPA_Depth 的問題是隻能指定顏色數量的 2 的倍數。GTPA_NumColors 允許任何數量的顏色。
http://thomas-rapp.homepage.t-online.de/examples/gtmenu.c
設定 GadTools 選單
GetVisualInfo() and FreeVisualInfo() CreateContext()
下劃線字元“_”是推薦的標記符號。因此,例如,要將字母“F”標記為“選擇字型...”按鈕的鍵盤等效項,請建立元件文字
ng.ng_GadgetText = "Select _Font...";
http://thomas-rapp.homepage.t-online.de/examples/lv.c
當多次呼叫 CreateGadget()(對於每個元件)時,每個新元件都會自動連結到前一個元件的 NextGadget 欄位,從而建立一個元件列表。其次,如果其中一個元件建立失敗(通常是由於記憶體不足,但也可能是其他原因),則對於下一次呼叫 CreateGadget(),next_gad 將為 NULL,並且 CreateGadget() 將立即失敗。這意味著程式可以執行多次連續的 CreateGadget() 呼叫,並且只需要在最後檢查失敗。
不能在視窗邊框中使用 GadTools 捲軸元件
http://thomas-rapp.homepage.t-online.de/examples/scroll.c http://thomas-rapp.homepage.t-online.de/examples/iconify.c
分配一個包含 imageclass 的物件,然後使用它將圖形繪製到按鈕中
/*
Copyright © 1995-2007, The AROS Development Team. All rights reserved.
$Id: calculator.c 27035 2007-10-07 19:33:35Z mazze $
*/
#include <intuition/intuition.h>
#include <libraries/gadtools.h>
#include <libraries/locale.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/intuition.h>
#include <proto/graphics.h>
#include <proto/gadtools.h>
#include <proto/locale.h>
#include <proto/alib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <math.h>
#define ARG_TEMPLATE "PUBSCREEN,TAPE/K"
enum {ARG_PUBSCREEN,ARG_TAPE,NUM_ARGS};
#define MAX_VAL_LEN 13
#define INNER_SPACING_X 4
#define INNER_SPACING_Y 4
#define BUTTON_SPACING_X 4
#define BUTTON_SPACING_Y 4
#define BUTTON_LED_SPACING 4
#define NUM_BUTTONS 20
#define NUM_BUTTON_COLS 5
#define NUM_BUTTON_ROWS 4
#define BUTTON_EXTRA_WIDTH 8
#define BUTTON_EXTRA_HEIGHT 4
#define LED_EXTRA_HEIGHT 4
enum
{
STATE_LEFTVAL, STATE_OP, STATE_RIGHTVAL, STATE_EQU
};
enum
{
BTYPE_0,
BTYPE_1,
BTYPE_2,
BTYPE_3,
BTYPE_4,
BTYPE_5,
BTYPE_6,
BTYPE_7,
BTYPE_8,
BTYPE_9,
BTYPE_COMMA,
BTYPE_BS,
BTYPE_CA,
BTYPE_CE,
BTYPE_MUL,
BTYPE_DIV,
BTYPE_SUB,
BTYPE_ADD,
BTYPE_SIGN,
BTYPE_EQU,
BTYPE_LED
};
struct ButtonInfo
{
char *text;
WORD type;
char key1;
char key2;
};
static struct ButtonInfo bi[NUM_BUTTONS] =
{
{"7" ,BTYPE_7 , '7' , 0 },
{"8" ,BTYPE_8 , '8' , 0 },
{"9" ,BTYPE_9 , '9' , 0 },
{"CA" ,BTYPE_CA , 'A' , 127 },
{"CE" ,BTYPE_CE , 'E' , 0 },
{"4" ,BTYPE_4 , '4' , 0 },
{"5" ,BTYPE_5 , '5' , 0 },
{"6" ,BTYPE_6 , '6' , 0 },
{"×" ,BTYPE_MUL , '*' , 'X' },
{":" ,BTYPE_DIV , '/' , ':' },
{"1" ,BTYPE_1 , '1' , 0 },
{"2" ,BTYPE_2 , '2' , 0 },
{"3" ,BTYPE_3 , '3' , 0 },
{"+" ,BTYPE_ADD , '+' , 0 },
{"-" ,BTYPE_SUB , '-' , 0 },
{"0" ,BTYPE_0 , '0' , 0 },
{"." ,BTYPE_COMMA , '.' , ',' },
{"«" ,BTYPE_BS , 8 , 0 },
{"±" ,BTYPE_SIGN , 'S' , 0 },
{"=" ,BTYPE_EQU , '=' , 13 }
};
struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct Library *GadToolsBase;
#ifndef __MORPHOS__
struct LocaleBase *LocaleBase;
#else
struct Library *LocaleBase;
#endif
static struct Screen *scr;
static struct DrawInfo *dri;
static struct Gadget *gadlist, *gad[NUM_BUTTONS + 2];
static struct Window *win;
static struct RDArgs *MyArgs;
static APTR vi;
static BPTR tapefh;
static WORD win_borderleft,win_bordertop;
static WORD buttonwidth,buttonheight,ledheight;
static WORD inner_winwidth,inner_winheight;
static WORD vallen,state,operation;
static BOOL dotape;
static double leftval,rightval;
static char comma,*pubscrname;
static char ledstring[256],visledstring[256],
tempstring[256],tapename[256];
static char *deftapename = "RAW:%ld/%ld/%ld/%ld/Calculator Tape/INACTIVE/SCREEN%s";
UBYTE version[] = "$VER: Calculator 1.3 (07.10.2007) © AROS Dev Team";
static IPTR Args[NUM_ARGS];
static void Cleanup(char *msg)
{
WORD rc;
if (msg)
{
printf("Calculator: %s\n",msg);
rc = RETURN_WARN;
} else {
rc = RETURN_OK;
}
if (tapefh) Close(tapefh);
if (win) CloseWindow(win);
if (gadlist) FreeGadgets(gadlist);
if (vi) FreeVisualInfo(vi);
if (dri) FreeScreenDrawInfo(scr,dri);
if (scr) UnlockPubScreen(0,scr);
if (MyArgs) FreeArgs(MyArgs);
if (LocaleBase) CloseLibrary((struct Library *)LocaleBase);
if (GadToolsBase) CloseLibrary(GadToolsBase);
if (GfxBase) CloseLibrary((struct Library *)GfxBase);
if (IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
exit (rc);
}
static void DosError(void)
{
Fault(IoErr(),0,tempstring,255);
Cleanup(tempstring);
}
static void OpenLibs(void)
{
if (!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",39)))
{
Cleanup("Can't open intuition.library V39!");
}
if (!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",39)))
{
Cleanup("Can't open graphics.library V39!");
}
if (!(GadToolsBase = OpenLibrary("gadtools.library",39)))
{
Cleanup("Can't open gadtools.library V39!");
}
LocaleBase = (struct LocaleBase *)OpenLibrary("locale.library",39);
}
static void GetArguments(void)
{
if (!(MyArgs = ReadArgs(ARG_TEMPLATE,(IPTR *)Args,0)))
{
DosError();
}
pubscrname = (char *)Args[ARG_PUBSCREEN];
if (Args[ARG_TAPE])
{
strcpy(tapename,(char *)Args[ARG_TAPE]);
dotape = TRUE;
}
}
static void DoLocale(void)
{
struct Locale *loc;
comma = '.';
if ((loc = OpenLocale(0)))
{
comma = loc->loc_DecimalPoint[0];
CloseLocale(loc);
}
bi[16].text[0] = comma;
}
static void GetVisual(void)
{
if (pubscrname) scr = LockPubScreen(pubscrname);
if (!scr)
{
if (!(scr = LockPubScreen(0)))
{
Cleanup("Can't lock screen!");
}
}
if (!(dri = GetScreenDrawInfo(scr)))
{
Cleanup("Can't get drawinfo!");
}
if (!(vi = GetVisualInfo(scr,0)))
{
Cleanup("Can't get visual info!");
}
win_borderleft = scr->WBorLeft;
/* SDuvan: was scr->WBorTop + scr->Font->ta_YSize + 1 */
win_bordertop = scr->WBorTop + dri->dri_Font->tf_YSize + 1;
}
static void InitGUI(void)
{
static struct RastPort temprp;
WORD i,len;
InitRastPort(&temprp);
SetFont(&temprp,dri->dri_Font);
buttonheight = dri->dri_Font->tf_YSize + BUTTON_EXTRA_HEIGHT;
for(i = 0;i < NUM_BUTTONS;i++)
{
len = TextLength(&temprp,bi[i].text,strlen(bi[i].text));
if (len > buttonwidth) buttonwidth = len;
}
buttonwidth += BUTTON_EXTRA_WIDTH;
ledheight = dri->dri_Font->tf_YSize + LED_EXTRA_HEIGHT;
inner_winwidth = buttonwidth * NUM_BUTTON_COLS +
BUTTON_SPACING_X * (NUM_BUTTON_COLS - 1) +
INNER_SPACING_X * 2;
inner_winheight = buttonheight * NUM_BUTTON_ROWS +
BUTTON_SPACING_Y * (NUM_BUTTON_ROWS - 1) +
BUTTON_LED_SPACING +
ledheight +
INNER_SPACING_Y * 2;
#ifdef __AROS__
DeinitRastPort(&temprp);
#endif
strcpy(ledstring,"0");
}
static void MakeGadgets(void)
{
struct Gadget *mygad = 0;
struct NewGadget ng = {0};
WORD col,row,i;
ng.ng_VisualInfo = vi;
mygad = CreateContext(&gadlist);
ng.ng_GadgetID = BTYPE_LED;
ng.ng_LeftEdge = win_borderleft + INNER_SPACING_X;
ng.ng_TopEdge = win_bordertop + INNER_SPACING_Y;
ng.ng_Width = inner_winwidth - INNER_SPACING_X * 2;
ng.ng_Height = ledheight;
mygad = gad[BTYPE_LED] = CreateGadget(TEXT_KIND,
mygad,
&ng,
GTTX_Text, (IPTR) ledstring,
GTTX_CopyText,TRUE,
GTTX_Border,TRUE,
GTTX_Justification,GTJ_RIGHT,
TAG_DONE);
i = 0;
ng.ng_TopEdge = win_bordertop +
INNER_SPACING_Y +
ledheight +
BUTTON_LED_SPACING;
ng.ng_Width = buttonwidth;
ng.ng_Height = buttonheight;
for(row = 0; row < NUM_BUTTON_ROWS; row++)
{
for(col = 0; col < NUM_BUTTON_COLS; col++, i++)
{
ng.ng_GadgetID = bi[i].type;
ng.ng_LeftEdge = win_borderleft +
INNER_SPACING_X +
col * (buttonwidth + BUTTON_SPACING_X);
ng.ng_GadgetText = bi[i].text;
mygad = gad[bi[i].type] = CreateGadgetA(BUTTON_KIND,
mygad,
&ng,
0);
} /* for(col = 0;col < NUM_BUTTON_COLS; col++) */
ng.ng_TopEdge += buttonheight + BUTTON_SPACING_Y;
} /* for(row = 0; row < NUM_BUTTON_ROWS; row++) */
if (!mygad)
{
Cleanup("Can't create gadgets!");
}
}
static void MakeWin(void)
{
win = OpenWindowTags(0,WA_PubScreen,(IPTR)scr,
WA_Left,scr->MouseX,
WA_Top,scr->MouseY,
WA_InnerWidth,inner_winwidth,
WA_InnerHeight,inner_winheight,
WA_AutoAdjust,TRUE,
WA_Title,(IPTR)"Calculator",
WA_CloseGadget,TRUE,
WA_DepthGadget,TRUE,
WA_DragBar,TRUE,
WA_Activate,TRUE,
WA_SimpleRefresh,TRUE,
WA_IDCMP,IDCMP_CLOSEWINDOW |
IDCMP_GADGETUP |
IDCMP_VANILLAKEY |
IDCMP_RAWKEY |
IDCMP_REFRESHWINDOW,
WA_Gadgets,(IPTR)gadlist,
TAG_DONE);
if (!win) Cleanup("Can't open window!");
GT_RefreshWindow(win,0);
ScreenToFront(win->WScreen);
}
static void OpenTape(void)
{
struct List *l;
struct PubScreenNode *psn;
char *scrname = "";
WORD x,y,w,h;
if (!(tapename[0]))
{
l = LockPubScreenList();
psn = (struct PubScreenNode *)l->lh_Head;
while (psn->psn_Node.ln_Succ)
{
if (psn->psn_Screen == scr)
{
if (psn->psn_Node.ln_Name)
{
scrname = psn->psn_Node.ln_Name;
}
break;
}
psn = (struct PubScreenNode *)psn->psn_Node.ln_Succ;
}
UnlockPubScreenList();
w = win->Width * 5 / 4;
h = win->Height;
x = win->LeftEdge;
y = win->TopEdge;
if (x > (scr->Width - (x + w)))
{
x -= w;
} else {
x += win->Width;
}
sprintf(tapename,deftapename,x,y,w,h,scrname);
}
if (!(tapefh = Open(tapename,MODE_NEWFILE)))
{
DisplayBeep(scr);
}
}
static double GetValue(void)
{
double val;
char c = 0,*sp;
sp = strchr(ledstring,comma);
if (sp)
{
c = *sp;
*sp = '.';
}
val = strtod(ledstring,0);
if (sp) *sp = c;
return val;
}
static void GetLeftValue(void)
{
leftval = GetValue();
}
static void GetRightValue(void)
{
rightval = GetValue();
}
static void LeftValToLED(void)
{
char *sp;
sprintf(ledstring,"%f",leftval);
sp = strchr(ledstring,'.');
if (!sp) sp = strchr(ledstring,',');
if (sp) *sp = comma;
}
static char *DoOperation(void)
{
char *matherr = 0;
switch (operation)
{
case BTYPE_ADD:
leftval += rightval;
break;
case BTYPE_SUB:
leftval -= rightval;
break;
case BTYPE_MUL:
leftval *= rightval;
break;
case BTYPE_DIV:
if (rightval == 0.0)
{
matherr = "Division by zero!";
} else {
leftval /= rightval;
}
break;
}
if (leftval > 9999999999999.0) // because of MAX_VAL_LEN
{
matherr = "Buffer overflow!";
}
if (!matherr) LeftValToLED();
return matherr;
}
static void RefreshLED(void)
{
strcpy(visledstring,ledstring);
if ((ledstring[0] == ',') ||
(ledstring[0] == '\0') ||
((ledstring[0] >= '0') && (ledstring[0] <= '9')))
{
visledstring[0] = '\0';
if ((ledstring[0] == ',') ||
(ledstring[0] == '.') ||
(ledstring[0] == '\0'))
{
strcpy(visledstring,"0");
}
strcat(visledstring,ledstring);
}
GT_SetGadgetAttrs(gad[BTYPE_LED],
win,
0,
GTTX_Text,(IPTR)visledstring,
TAG_DONE);
}
static void HandleButton(WORD type)
{
char *matherr = 0;
WORD checklen;
BOOL refresh_led = FALSE;
switch(type)
{
case BTYPE_0:
case BTYPE_1:
case BTYPE_2:
case BTYPE_3:
case BTYPE_4:
case BTYPE_5:
case BTYPE_6:
case BTYPE_7:
case BTYPE_8:
case BTYPE_9:
checklen = vallen;
if ((strchr(ledstring,comma))) checklen--;
if ((strchr(ledstring,'-'))) checklen--;
if (checklen < MAX_VAL_LEN)
{
if (state == STATE_OP)
{
state = STATE_RIGHTVAL;
} else if (state == STATE_EQU)
{
state = STATE_LEFTVAL;
}
if ((vallen > 0) || (type != BTYPE_0))
{
ledstring[vallen++] = type + '0';
}
ledstring[vallen] = '\0';
refresh_led = TRUE;
} /* if (vallen < MAX_VAL_LEN) */
break;
case BTYPE_COMMA:
if (!strchr(ledstring,comma))
{
if (state == STATE_OP)
{
state = STATE_RIGHTVAL;
} else if (state == STATE_EQU)
{
state = STATE_LEFTVAL;
}
ledstring[vallen++] = comma;
ledstring[vallen] = '\0';
refresh_led = TRUE;
} /* if (!strchr(ledstring,comma)) */
break;
case BTYPE_CA:
vallen = 0;
leftval = 0.0;
rightval = 0.0;
operation = BTYPE_ADD;
state = STATE_LEFTVAL;
strcpy(ledstring,"0");
refresh_led = TRUE;
if (tapefh) FPutC(tapefh, '\n');
break;
case BTYPE_CE:
vallen = 0;
strcpy(ledstring,"0");
refresh_led = TRUE;
switch (state)
{
case STATE_LEFTVAL:
leftval = 0.0;
break;
case STATE_OP:
case STATE_RIGHTVAL:
rightval = 0.0;
break;
}
break;
case BTYPE_BS:
if (vallen)
{
ledstring[--vallen] = '\0';
if (vallen == 0) strcpy(ledstring,"0");
refresh_led = TRUE;
}
break;
case BTYPE_SIGN:
switch(state)
{
case STATE_LEFTVAL:
case STATE_RIGHTVAL:
if (ledstring[0] == '-')
{
strcpy(ledstring,&ledstring[1]);
} else {
strcpy(tempstring,ledstring);
strcpy(ledstring,"-");
strcat(ledstring,tempstring);
}
refresh_led = TRUE;
break;
case STATE_EQU:
leftval = -leftval;
LeftValToLED();
refresh_led = TRUE;
break;
}
break;
case BTYPE_ADD:
case BTYPE_SUB:
case BTYPE_MUL:
case BTYPE_DIV:
switch(state)
{
case STATE_LEFTVAL:
case STATE_EQU:
GetLeftValue();
rightval = leftval;
state = STATE_OP;
vallen = 0;
strcpy(ledstring,"0");
if (tapefh)
{
FPutC(tapefh, '\t');
FPuts(tapefh, visledstring);
FPutC(tapefh, '\n');
Flush(tapefh);
}
break;
case STATE_OP:
break;
case STATE_RIGHTVAL:
GetRightValue();
matherr = DoOperation();
state = STATE_OP;
vallen = 0;
refresh_led = TRUE;
if (tapefh)
{
FPuts(tapefh,
(operation == BTYPE_ADD) ? "+" :
(operation == BTYPE_SUB) ? "-" :
(operation == BTYPE_DIV) ? ":" :
"×");
FPutC(tapefh, '\t');
FPuts(tapefh, visledstring);
FPutC(tapefh, '\n');
Flush(tapefh);
}
break;
} /* switch(state) */
operation = type;
break;
case BTYPE_EQU:
if (state == STATE_LEFTVAL)
{
GetLeftValue();
if (tapefh)
{
FPutC(tapefh, '\t');
FPuts(tapefh, visledstring);
FPutC(tapefh, '\n');
Flush(tapefh);
}
}
else if (state == STATE_RIGHTVAL)
{
GetRightValue();
if (tapefh)
{
FPuts(tapefh,
(operation == BTYPE_ADD) ? "+" :
(operation == BTYPE_SUB) ? "-" :
(operation == BTYPE_DIV) ? ":" :
"×");
FPutC(tapefh, '\t');
FPuts(tapefh, visledstring);
FPutC(tapefh, '\n');
Flush(tapefh);
}
}
matherr = DoOperation();
state = STATE_EQU;
vallen = 0;
if (!matherr)
{
RefreshLED();
if (tapefh)
{
FPuts(tapefh, "=\t");
FPuts(tapefh, visledstring);
FPutC(tapefh, '\n');
Flush(tapefh);
}
} else {
refresh_led = TRUE;
}
break;
} /* switch(type) */
if (matherr)
{
leftval = rightval = 0.0;
state = STATE_LEFTVAL;
operation = BTYPE_ADD;
vallen = 0;
strcpy(ledstring,matherr);
refresh_led = TRUE;
}
if (refresh_led) RefreshLED();
}
static void HandleAll(void)
{
struct IntuiMessage *msg;
WORD icode,i;
ULONG signals;
BOOL quitme = FALSE;
if (dotape) OpenTape();
while(!quitme)
{
signals = Wait(1L << win->UserPort->mp_SigBit | SIGBREAKF_CTRL_C);
if (signals & (1L << win->UserPort->mp_SigBit))
{
while ((msg = (struct IntuiMessage *)GetMsg(win->UserPort)))
{
switch(msg->Class)
{
case IDCMP_CLOSEWINDOW:
quitme = TRUE;
break;
case IDCMP_REFRESHWINDOW:
GT_BeginRefresh(win);
GT_EndRefresh(win,TRUE);
break;
case IDCMP_GADGETUP:
HandleButton(((struct Gadget *)msg->IAddress)->GadgetID);
break;
case IDCMP_VANILLAKEY:
icode = toupper(msg->Code);
for(i = 0;i < NUM_BUTTONS;i++)
{
if ((icode == bi[i].key1) ||
(icode == bi[i].key2))
{
icode = bi[i].type;
break;
}
}
if (i < NUM_BUTTONS)
{
HandleButton(icode);
} else if (icode == 27)
{
quitme = TRUE;
}
break;
} /* switch(msg->Class) */
ReplyMsg((struct Message *)msg);
} /* while ((msg = (struct IntuiMessage *)GetMsg(win->UserPort))) */
} /* if(signals & (1L << win->UserPort->mp_SigBit)) */
if (signals & SIGBREAKF_CTRL_C)
quitme = TRUE;
} /* while(!quitme) */
}
int main(void)
{
OpenLibs();
GetArguments();
DoLocale();
GetVisual();
InitGUI();
MakeGadgets();
MakeWin();
HandleAll();
Cleanup(0);
return 0;
}
/* Menus for LiteBench */
#ifdef WB_1.3
/*
* Workbench 1.3 style menus (obsolete)
*
* Workbench
* Open
* Close
* Duplicate
* Rename
* Info
* Discard
*
* Disk
* Empty Disk
* Initialize
*
* Special
* Clean up
* Last error
* Redraw
* Snapshot
* Version
*/
struct NewMenu mynewmenu[] =
{
{ NM_TITLE, "Workbench", 0, 0, 0, 0, },
{ NM_ITEM, "Open" 0 0, 0, 0, },
{ NM_ITEM, "Close", 0, 0, 0, 0, },
{ NM_ITEM, "Duplicate", 0, 0, 0, 0, },
{ NM_ITEM, "Rename", 0, 0, 0, 0, },
{ NM_ITEM, "Info", 0, 0, 0, 0, },
{ NM_ITEM, "Discard", 0, 0, 0, 0, },
{ NM_TITLE, "Disk", 0, 0, 0, 0, },
{ NM_ITEM, "Empty Disk", 0, 0, 0, 0, },
{ NM_ITEM, "Initialize", 0, 0, 0, 0, },
{ NM_TITLE, "Special", 0, 0, 0, 0, },
{ NM_ITEM, "Clean Up", 0, 0, 0, 0, },
{ NM_ITEM, "Last Error" 0, 0, 0, 0, },
{ NM_ITEM, "Redraw", 0, 0, 0, 0, },
{ NM_ITEM, "Snapshot", 0, 0, 0, 0, },
{ NM_ITEM, "Version", 0, 0, 0, 0, },
{ NM_END, NULL, 0, 0, 0, 0, },
};
#endif /* WB_1.3 */
#ifdef LITEBENCH
/* simplified menus for a minimal workbench program */
struct NewMenu mynewmenu[] =
{
{ NM_TITLE, "Icon", 0, 0, 0, 0, },
{ NM_ITEM, "Open", "O", 0, 0, 0, },
{ NM_ITEM, "Copy", "C", 0, 0, 0, },
{ NM_ITEM, "Rename...", "R", 0, 0, 0, },
{ NM_ITEM, "Information...", "I", 0, 0, 0, },
{ NM_ITEM, "Snapshot", "S", 0, 0, 0, },
{ NM_ITEM, "Unsnapshot", "U", 0, 0, 0, },
{ NM_ITEM, "Leave out", "L", 0, 0, 0, },
{ NM_ITEM, "Put away", "P", 0, 0, 0, },
{ NM_ITEM, NM_BARLABEL, 0, 0, 0, 0, },
{ NM_ITEM, "Delete...", 0, 0, 0, 0, },
{ NM_ITEM, "Format...", 0, 0, 0, 0, },
{ NM_ITEM, "Empty trash", 0, 0, 0, 0, },
{ NM_TITLE, "Window", 0, 0, 0, 0, },
{ NM_ITEM, "New drawer", "N", 0, 0, 0, },
{ NM_ITEM, "Open parent", "K", 0, 0, 0, },
{ NM_ITEM, "Close", 0, 0, 0, 0, },
{ NM_ITEM, "Update", 0, 0, 0, 0, },
{ NM_ITEM, "Select contents", "A", 0, 0, 0, },
{ NM_ITEM, "Clean up by", 0, 0, 0, 0, },
{ NM_SUB, "Column", ".", 0, 0, 0, },
{ NM_SUB, NM_BARLABEL, 0, 0, 0, 0, },
{ NM_SUB, "Name", 0, (CHECKIT), 0, 0, },
{ NM_SUB, "Date", 0, (CHECKIT), 0, 0, },
{ NM_SUB, "Size", 0, (CHECKIT), 0, 0, },
{ NM_SUB, "Type", 0, (CHECKIT), 0, 0, },
{ NM_ITEM, "Resize to fit", 0, 0, 0, 0, },
{ NM_ITEM, "Snapshot", 0, 0, 0, 0, },
{ NM_SUB, "Window", 0, 0, 0, 0, },
{ NM_SUB, "All", 0, 0, 0, 0, },
{ NM_ITEM, "Show", 0, 0, 0, 0, },
{ NM_SUB, "Only icons", "-", 0, 0, 0, },
{ NM_SUB, "All files", "+", 0, 0, 0, },
{ NM_ITEM, "View by", 0, 0, 0, 0, },
{ NM_SUB, "Icon", "1", 0, 0, 0, },
{ NM_SUB, NM_BARLABEL, 0 , 0, 0, 0, },
{ NM_SUB, "Name", "2", 0, 0, 0, },
{ NM_SUB, "Date", "3", 0, 0, 0, },
{ NM_SUB, "Size", "4", 0, 0, 0, },
{ NM_SUB, "Type", "5", 0, 0, 0, },
{ NM_TITLE, "Special" 0, 0, 0, 0, },
{ NM_ITEM, "New Shell..." "W",0,0,0, },
{ NM_ITEM, "Icon Editor..." "Y",0,0,0, },
{ NM_ITEM, NM_BARLABEL, 0, 0, 0, 0, },
{ NM_ITEM, "Quit Litebench", "Q", 0, 0, 0, },
{ NM_END, NULL, 0, 0, 0, 0, },
};
#endif /* LITEBENCH */
#ifdef WB_3.x
/* Workbench 3.x compatible menu strips, same keyboard shortcuts, etc.
* *
* Workbench
* x Backdrop [a]B
* Enter Command [a]E
* Redraw all
* Update all
* Last Message
* About...
* Quit [a]Q
*
* Window
* New drawer [a]N
* Open parent [a]K
* Close
* Update
* Select Contents [a]A
* Clear selection [a]Z
* Clean up by >>
* Column [a]. {period}
* -------------------
* Name
* Date
* Size
* Type
* Resize to fit
* Snapshot >>
* Window
* All
* Show >>
* Only icons [a] - {minus}
* All files [a] + {plus}
* View by >>
* Icon [a] 1 {one}
* ------------------
* Name [a] 2 {two}
* Date [a] 3 {three}
* Size [a] 4 {four}
* Type [a] 5 {five}
*
* Icons
* Open [a]O
* Copy [a]C
* Rename... [a]R
* Information... a[I]
* Snapshot [a]S
* Unsnapshot [a]U
* Leave out [a]L
* Put away a[P]
* -------------------
* Delete....
* Format....
* Empty Trash
*
* Tools
* ResetWB
*
*/
struct NewMenu mynewmenu[] =
{
{ NM_TITLE, "Workbench", 0, 0, 0, 0, },
{ NM_ITEM, "Backdrop", "B", (CHECKIT|CHECKED), 0, 0, },
{ NM_ITEM, "Enter command", "E", 0, 0, 0, },
{ NM_ITEM, "Redraw all", 0, 0, 0, 0, },
{ NM_ITEM, "Update all", 0, 0, 0, 0, },
{ NM_ITEM, "Last message", 0, 0, 0, 0, },
{ NM_ITEM, "About...", 0, 0, 0, 0, },
{ NM_ITEM, "Quit", "Q", 0, 0, 0, },
{ NM_TITLE, "Window", 0, 0, 0, 0, },
{ NM_ITEM, "New drawer", "N", 0, 0, 0, },
{ NM_ITEM, "Open parent", "K", 0, 0, 0, },
{ NM_ITEM, "Close", 0, 0, 0, 0, },
{ NM_ITEM, "Update", 0, 0, 0, 0, },
{ NM_ITEM, "Select contents", "A", 0, 0, 0, },
{ NM_ITEM, "Clean up by", 0, 0, 0, 0, },
{ NM_SUB, "Column", ".", 0, 0, 0, },
{ NM_SUB, NM_BARLABEL, 0, 0, 0, 0, },
{ NM_SUB, "Name", 0, (CHECKIT), 0, 0, },
{ NM_SUB, "Date", 0, (CHECKIT), 0, 0, },
{ NM_SUB, "Size", 0, (CHECKIT), 0, 0, },
{ NM_SUB, "Type", 0, (CHECKIT), 0, 0, },
{ NM_ITEM, "Resize to fit", 0, 0, 0, 0, },
{ NM_ITEM, "Snapshot", 0, 0, 0, 0, },
{ NM_SUB, "Window", 0, 0, 0, 0, },
{ NM_SUB, "All", 0, 0, 0, 0, },
{ NM_ITEM, "Show", 0, 0, 0, 0, },
{ NM_SUB, "Only icons", "-", 0, 0, 0, },
{ NM_SUB, "All files", "+", 0, 0, 0, },
{ NM_ITEM, "View by", 0, 0, 0, 0, },
{ NM_SUB, "Icon", "1", 0, 0, 0, },
{ NM_SUB, NM_BARLABEL, 0 , 0, 0, 0, },
{ NM_SUB, "Name", "2", 0, 0, 0, },
{ NM_SUB, "Date", "3", 0, 0, 0, },
{ NM_SUB, "Size", "4", 0, 0, 0, },
{ NM_SUB, "Type", "5", 0, 0, 0, },
{ NM_ITEM, NM_BARLABEL, 0, 0, 0, 0, },
{ NM_ITEM, "Find...", "F", 0, 0, 0, },
{ NM_TITLE, "Icons", 0, 0, 0, 0, },
{ NM_ITEM, "Open", "O", 0, 0, 0, },
{ NM_ITEM, "Copy", "C", 0, 0, 0, },
{ NM_ITEM, "Rename...", "R", 0, 0, 0, },
{ NM_ITEM, "Information...", "I", 0, 0, 0, },
{ NM_ITEM, "Snapshot", "S", 0, 0, 0, },
{ NM_ITEM, "Unsnapshot", "U", 0, 0, 0, },
{ NM_ITEM, "Leave out", "L", 0, 0, 0, },
{ NM_ITEM, "Put away", "P", 0, 0, 0, },
{ NM_ITEM, NM_BARLABEL, 0, 0, 0, 0, },
{ NM_ITEM, "Delete...", 0, 0, 0, 0, },
{ NM_ITEM, "Format...", 0, 0, 0, 0, },
{ NM_ITEM, "Empty trash", 0, 0, 0, 0, },
{ NM_TITLE, "Tools", 0, 0, 0, 0, },
{ NM_ITEM, "ResetWB", 0, 0, 0, 0, },
{ NM_END, NULL, 0, 0, 0, 0, },
};
#endif /* WB_3.x */
#ifdef AROSbench /* enhanced WB_3.x style for AROS */
struct NewMenu mynewmenu[] =
{
{ NM_TITLE, "AROSbench", 0, 0, 0, 0, },
{ NM_ITEM, "Backdrop", "B", (CHECKIT|CHECKED), 0, 0, },
{ NM_ITEM, "Enter command", "E", 0, 0, 0, },
{ NM_ITEM, "New Shell", "W", 0, 0, 0, },
{ NM_ITEM, "Redraw all", 0, 0, 0, 0, },
{ NM_ITEM, "Update all", 0, 0, 0, 0, },
{ NM_ITEM, "Last message", 0, 0, 0, 0, },
{ NM_ITEM, "About AROSbench..." 0, 0, 0, 0, },
{ NM_ITEM, "Quit AROSbench", "Q", 0, 0, 0, },
{ NM_ITEM, NM_BARLABEL, 0, 0, 0, 0, },
{ NM_ITEM, "Shutdown AROS...", 0, 0, 0, 0, },
{ NM_TITLE, "Window", 0, 0, 0, 0, },
{ NM_ITEM, "New drawer", "N", 0, 0, 0, },
{ NM_ITEM, "Open parent", "K", 0, 0, 0, },
{ NM_ITEM, "Close", 0, 0, 0, 0, },
{ NM_ITEM, "Update", 0, 0, 0, 0, },
{ NM_ITEM, "Select contents","A", 0, 0, 0, },
{ NM_ITEM, "Clean up by", 0, 0, 0, 0, },
{ NM_SUB, "Column", ".", 0, 0, 0, },
{ NM_SUB, NM_BARLABEL, 0, 0, 0, 0, },
{ NM_SUB, "Name", 0, (CHECKIT), 0, 0, },
{ NM_SUB, "Date", 0, (CHECKIT), 0, 0, },
{ NM_SUB, "Size", 0, (CHECKIT), 0, 0, },
{ NM_SUB, "Type", 0, (CHECKIT), 0, 0, },
{ NM_ITEM, "Resize to fit", 0, 0, 0, 0, },
{ NM_ITEM, "Snapshot", 0, 0, 0, 0, },
{ NM_SUB, "Window", 0, 0, 0, 0, },
{ NM_SUB, "All", 0, 0, 0, 0, },
{ NM_ITEM, "Show", 0, 0, 0, 0, },
{ NM_SUB, "Only icons", "-", 0, 0, 0, },
{ NM_SUB, "All files", "+", 0, 0, 0, },
{ NM_ITEM, "View by", 0, 0, 0, 0, },
{ NM_SUB, "Icon", "1", 0, 0, 0, },
{ NM_SUB, NM_BARLABEL, 0 , 0, 0, 0, },
{ NM_SUB, "Name", "2", 0, 0, 0, },
{ NM_SUB, "Date", "3", 0, 0, 0, },
{ NM_SUB, "Size", "4", 0, 0, 0, },
{ NM_SUB, "Type", "5", 0, 0, 0, },
{ NM_ITEM, NM_BARLABEL, 0, 0, 0, 0, },
{ NM_ITEM, "Find...", "F", 0, 0, 0, },
{ NM_TITLE, "Icons", 0, 0, 0, 0, },
{ NM_ITEM, "Open", "O", 0, 0, 0, },
{ NM_ITEM, "Copy", "C", 0, 0, 0, },
{ NM_ITEM, "Rename...", "R", 0, 0, 0, },
{ NM_ITEM, "Information...", "I", 0, 0, 0, },
{ NM_ITEM, "Snapshot", "S", 0, 0, 0, },
{ NM_ITEM, "Unsnapshot", "U", 0, 0, 0, },
{ NM_ITEM, "Leave out", "L", 0, 0, 0, },
{ NM_ITEM, "Put away", "P", 0, 0, 0, },
{ NM_ITEM, NM_BARLABEL, 0, 0, 0, 0, },
{ NM_ITEM, "Delete...", 0, 0, 0, 0, },
{ NM_ITEM, "Format...", 0, 0, 0, 0, },
{ NM_ITEM, "Empty trash", 0, 0, 0, 0, },
{ NM_TITLE, "QuickAccess", 0, 0, 0, 0, },
{ NM_ITEM, "WBstartup files", 0, 0, 0, 0, },
{ NM_ITEM, "System preferences", 0, 0, 0, 0, },
{ NM_ITEM, "System scripts", 0, 0, 0, 0, },
{ NM_ITEM, "System tools", 0, 0, 0, 0, },
{ NM_ITEM, "System utilities" , 0, 0, 0, 0, },
{ NM_ITEM, "System fonts", 0, 0, 0, 0, },
{ NM_ITEM, "System deficons", 0, 0, 0, 0, },
{ NM_ITEM, "System temporary files", 0, 0, 0, 0, },
{ NM_ITEM, "Trashcan", 0, 0, 0, 0, },
{ NM_TITLE, "Tools", 0, 0, 0, 0, },
{ NM_END, NULL, 0, 0, 0, 0, },
};
#endif /* AROSbench */
/* gadtoolsmenu.c*/
#define INTUI_V36_NAMES_ONLY
#include <exec/types.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <libraries/gadtools.h>
#include <proto/exec.h>
#include <proto/gadtools.h>
#include <proto/intuition.h>
#include <stdio.h>
struct Library *GadToolsBase;
struct IntuitionBase *IntuitionBase;
struct NewMenu mynewmenu[] =
{
{ NM_TITLE, "Project", 0 , 0, 0, 0,},
{ NM_ITEM, "Open...", "O", 0, 0, 0,},
{ NM_ITEM, "Save", "S", 0, 0, 0,},
{ NM_ITEM, NM_BARLABEL, 0 , 0, 0, 0,},
{ NM_ITEM, "Print", 0 , 0, 0, 0,},
{ NM_SUB, "Draft", 0 , 0, 0, 0,},
{ NM_SUB, "NLQ", 0 , 0, 0, 0,},
{ NM_ITEM, NM_BARLABEL, 0 , 0, 0, 0,},
{ NM_ITEM, "Quit...", "Q", 0, 0, 0,},
{ NM_TITLE, "Edit", 0 , 0, 0, 0,},
{ NM_ITEM, "Cut", "X", 0, 0, 0,},
{ NM_ITEM, "Copy", "C", 0, 0, 0,},
{ NM_ITEM, "Paste", "V", 0, 0, 0,},
{ NM_ITEM, NM_BARLABEL, 0 , 0, 0, 0,},
{ NM_ITEM, "Undo", "Z", 0, 0, 0,},
{ NM_END, NULL, 0 , 0, 0, 0,},
};
/* Watch the menus and wait for the user to select the close gadget or quit from the menus. */
VOID handle_window_events(struct Window *win, struct Menu *menuStrip)
{
struct IntuiMessage *msg;
SHORT done;
UWORD menuNumber;
UWORD menuNum;
UWORD itemNum;
UWORD subNum;
struct MenuItem *item;
done = FALSE;
while (FALSE == done)
{
/* we only have one signal bit, so we do not have to check which
** bit broke the Wait().
*/
Wait(1L << win->UserPort->mp_SigBit);
while ( (FALSE == done) &&
(NULL != (msg = (struct IntuiMessage *)GetMsg(win->UserPort))))
{
switch (msg->Class)
{
case IDCMP_CLOSEWINDOW:
done = TRUE;
break;
case IDCMP_MENUPICK:
menuNumber = msg->Code;
while ((menuNumber != MENUNULL) && (!done))
{
item = ItemAddress(menuStrip, menuNumber);
/* process the item here! */
menuNum = MENUNUM(menuNumber);
itemNum = ITEMNUM(menuNumber);
subNum = SUBNUM(menuNumber);
/* stop if quit is selected. */
if ((menuNum == 0) && (itemNum == 5))
done = TRUE;
menuNumber = item->NextSelect;
}
break;
}
ReplyMsg((struct Message *)msg);
}
}
}
/*
** Open all of the required libraries and set-up the menus.
*/
VOID main(int argc, char *argv[])
{
struct Window *win;
APTR *my_VisualInfo;
struct Menu *menuStrip;
/* Open the Intuition Library */
IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 37);
if (IntuitionBase != NULL)
{
/* Open the gadtools Library */
GadToolsBase = OpenLibrary("gadtools.library", 37);
if (GadToolsBase != NULL)
{
if (NULL != (win = OpenWindowTags(NULL,
WA_Width, 400, WA_Activate, TRUE,
WA_Height, 100, WA_CloseGadget, TRUE,
WA_Title, "Menu Test Window",
WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_MENUPICK,
TAG_END)))
{
if (NULL != (my_VisualInfo = GetVisualInfo(win->WScreen, TAG_END)))
{
if (NULL != (menuStrip = CreateMenus(mynewmenu, TAG_END)))
{
if (LayoutMenus(menuStrip, my_VisualInfo, TAG_END))
{
if (SetMenuStrip(win, menuStrip))
{
handle_window_events(win,menuStrip);
ClearMenuStrip(win);
}
FreeMenus(menuStrip);
}
}
FreeVisualInfo(my_VisualInfo);
}
CloseWindow(win);
}
CloseLibrary((struct Library *)GadToolsBase);
}
CloseLibrary((struct Library *)IntuitionBase);
}
}
Coder's Clinic 3
CCCC OOOO DDDD EEEEEE CCCC L IIIII N N IIIII CCCC
C C O O D D E C C L I NN N I C C
C O O D D EEE C L I N NN N I C
C C O O D D E C C L I N NN I C C
CCCC OOOO DDDD EEEEEE CCCC LLLLLL IIIII N N IIIII CCCC
--------------------------------------------------------------------------
CODE CLINIC #3 I LUV GADGETS!!!
As promised, We will add a gadget to our window. First we have to
get some info on how to do this.
GADGETS:Two types of gadgets.
*FIRST TYPE OF GADGET:System
System gadgets are those that you see in the windows and screens
that you open. And we are not going to go much further than that.
*SECOND TYPE OF GADGET:Application
Application gadgets are the ones in which you create and
use in your own programs. They can be placed at any
location inside the window and can use any image.
There are four basic types of application gadgets.
[1] Boolean : OK buttons ect...
[2] Proportion : Sound level ect...
[3] String : Enter your name ect...
[4] Custom : New gadgets.
*****--------------------------------------------------
* N * I STRONGLY SUGGEST INVESTING IN THE COMPLETE |
* O * SET OF AMIGA ROM KERNEL MANUALS... AT THE |
* T * VERY LEAST YOU SHOULD TRY TO GET THE LIBRARIES|
* E * MANUAL ...THERE ARE MANY EXAMPLES/EXPLANATIONS|
*****--------------------------------------------------
To create a gadget you simply fill in a Gadget structure.
(see fig.�1). You may also use the Gadtools Library to create
gadgets (which we will), As you can see the Gadget structure has
many items
and to cover all these would struct Gadget
consume a great deal of text {
as suggested before get the struct Gadget *NextGadget
ROM Kernel manual:Libraries WORD LeftEdge, TopEdge;
(at the very least) as there WORD Width, Height;
is detailed information on all UWORD Flags;
structures the amiga programmer UWORD Activation;
needs to understand. UWORD GadgetType;
APTR GadgetRender;
OK lets do something different APTR SelectRender;
like use the Gadtools Library struct IntuiText *GadgetText;
to put some gadgets up on the LONG MutualExclude;
window and let us know which one APTR SpecialInfo;
we selected. UWORD GadgetID;
APTR UserData;
Now that we know about the };
Intuistion gadgets lets take a FIG. 1
look at the Gadtools gadgets.
There are 12 types of gadgets that the Gadtools library supports
and they are:
Button
String
Integer
Checkboxes
Mutually exclusive
Cycle
Sliders
Scrollers
Listviews
Palette
Text-display
Numeric-display
With all of these types of gads what couldnt you do? And as a real
bonus there are several GUI buiders on aminet, just look in dev/gui
and you will see several I personally like GadToolBox by Jan van den
Baard. These programs take a great deal of coding off of your back
and allow you to work on the inner workings of your own program.
Lets take a look a the structure used to create a gadtools gadget:
struct NewGadget
{
WORD ng_LeftEdge,ng_TopEdge;
WORD ng_Width,ng_Height;
UBYTE *ng_GadgetText;
struct TextAttr *ng_TextAttr;
UWORD ng_GadgetID;
ULONG ng_Flags;
APTR ng_VisualInfo;
APTR ng_UserData;
};
FIG 2
If you compare the Gadget (fig 1) and the NewGadget (fig 2)
structures you will see some common items.
The way you create a gadget using gadtools is the CreateGadget()
function, its prototype is:
struct Gadget *CreateGadget(ULONG kind,
struct Gadget *prevgad,
struct NewGadget *newgad,
struct TagItem *taglist);
so to create a single button gadget we would do it like this:
ng.ng_TextAttr = &Topaz80;
ng,ng_VisualInfo = vi;
ng.ng_LeftEdge = 10;
ng.ng_TopEdge = 10;
ng.ng_Width = 60;
ng.ng_Height = 12;
ng.ng_GadgetText = "CLICK";
ng.ng_GadgetID = 1;
ng.ng_Flags = 0;
gad = CreateGadget(BUTTON_KIND,gad,&ng,TAG_END);
_____________________________
If you look at fig 2 you will []hello__________________[][]
see that we have filled the | |
structure and then made a call | CLICK QUIT |
to CreateGadget(). The nice | |
thing is that if you were to | |
add another gadget you now only | |
fill in the items that will | |
change, an example of this | |
is given below. Lets add a |___________________________|
gadget that has "QUIT" inside
it. FIG 4
ng.LeftEdge =80;
ng.ng_GadgetText ="QUIT";
ng.ng_GadgetID =2;
gad = CreateGadget(BUTTON_KIND,gad,&ng,TAG_END);
and now we would have two gadgets that would look like fig�4
The example program was created using the example from the ROM
Kernel Manual:Libraries in the chapter Gadtools Library pg.383-385.
I would also like to mention that this layout was written by me and
not by a GUI builder... and this is the GUI that we will use to
create our AddressBook program.
There are several new items to this code and alot of it you will not
understand, I will try to clear up any questions in the next issue
as we will go line by line of this code and explain what is going
on...
*****------------------------- *****-------------------------
* N * ALL CODE IS INTENDED | * N * I COMPILED THIS CODE |
* O * FOR VERSION 2.0 OR | * O * WITH SAS/C V6.0 AND |
* T * ABOVE... | * T * HAD NO ERRORS OR |
* E * | * E * WARNINGS |
*****------------------------- *****-------------------------
//.C..C.O.D.E..............................................................
#include <exec/types.h>
#include <intuition/intuition.h>
#include <intuition/gadgetclass.h>
#include <libraries/gadtools.h>
#include <clib/exec_protos.h>
#include <clib/intuition_protos.h>
#include <clib/gadtools_protos.h>
#include <stdio.h>
VOID process_window_events(struct Window *); VOID gadtoolsWindow(VOID);
VOID Do_Gad(struct Window *mywin,struct Gadget *gad,UWORD code); BOOL
terminated = FALSE; struct TextAttr Topaz80 = { "topaz.font",8,0,0,};
struct Library *IntuitionBase; struct Library *GadToolsBase;
void main(void) {
if ((IntuitionBase = OpenLibrary("intuition.library",37))!=NULL)
{
if ((GadToolsBase = OpenLibrary("gadtools.library",37))!=NULL)
{
gadtoolsWindow();
CloseLibrary(GadToolsBase);
}
CloseLibrary(IntuitionBase);
} }
VOID gadtoolsWindow(VOID) { struct Screen *mysc; struct Window *mywin;
struct Gadget *glist, *gad; struct NewGadget ng; void *vi;
glist = NULL;
if ((mysc = LockPubScreen(NULL)) != NULL)
{
if ((vi = GetVisualInfo(mysc, TAG_END)) != NULL)
{
gad = CreateContext(&glist);
ng.ng_TextAttr =&Topaz80;
ng.ng_VisualInfo =vi;
ng.ng_LeftEdge =300;
ng.ng_TopEdge =2+mysc->WBorTop+(mysc->Font->ta_YSize+1);
ng.ng_Width =16;
ng.ng_Height =12;
ng.ng_GadgetText ="A";
ng.ng_GadgetID =1;
ng.ng_Flags =0;
gad= CreateGadget(BUTTON_KIND,gad,&ng,TAG_END);
ng.ng_LeftEdge +=18 ;
ng.ng_GadgetText ="B";
ng.ng_GadgetID =2;
gad= CreateGadget(BUTTON_KIND,gad,&ng,TAG_END);
ng.ng_LeftEdge +=18 ;
ng.ng_GadgetText ="C";
ng.ng_GadgetID ++;
gad= CreateGadget(BUTTON_KIND,gad,&ng,TAG_END);
ng.ng_LeftEdge +=18 ;
ng.ng_GadgetText ="D";
ng.ng_GadgetID ++;
gad= CreateGadget(BUTTON_KIND,gad,&ng,TAG_END);
ng.ng_LeftEdge +=18 ;
ng.ng_GadgetText ="E";
ng.ng_GadgetID ++;
gad= CreateGadget(BUTTON_KIND,gad,&ng,TAG_END);
ng.ng_LeftEdge =300;
ng.ng_TopEdge +=14;
ng.ng_GadgetText ="F";
ng.ng_GadgetID ++;
gad= CreateGadget(BUTTON_KIND,gad,&ng,TAG_END);
ng.ng_LeftEdge +=18 ;
ng.ng_GadgetText ="G";
ng.ng_GadgetID ++;
gad= CreateGadget(BUTTON_KIND,gad,&ng,TAG_END);
ng.ng_LeftEdge +=18 ;
ng.ng_GadgetText ="H";
ng.ng_GadgetID ++;
gad= CreateGadget(BUTTON_KIND,gad,&ng,TAG_END);
ng.ng_LeftEdge +=18 ;
ng.ng_GadgetText ="I";
ng.ng_GadgetID ++;
gad= CreateGadget(BUTTON_KIND,gad,&ng,TAG_END);
ng.ng_LeftEdge +=18 ;
ng.ng_GadgetText ="J";
ng.ng_GadgetID ++;
gad= CreateGadget(BUTTON_KIND,gad,&ng,TAG_END);
ng.ng_LeftEdge =300;
ng.ng_TopEdge +=14;
ng.ng_GadgetText ="K";
ng.ng_GadgetID ++;
gad= CreateGadget(BUTTON_KIND,gad,&ng,TAG_END);
ng.ng_LeftEdge +=18 ;
ng.ng_GadgetText ="L";
ng.ng_GadgetID ++;
gad= CreateGadget(BUTTON_KIND,gad,&ng,TAG_END);
ng.ng_LeftEdge +=18 ;
ng.ng_GadgetText ="M";
ng.ng_GadgetID ++;
gad= CreateGadget(BUTTON_KIND,gad,&ng,TAG_END);
ng.ng_LeftEdge +=18 ;
ng.ng_GadgetText ="N";
ng.ng_GadgetID ++;
gad= CreateGadget(BUTTON_KIND,gad,&ng,TAG_END);
ng.ng_LeftEdge +=18 ;
ng.ng_GadgetText ="O";
ng.ng_GadgetID ++;
gad= CreateGadget(BUTTON_KIND,gad,&ng,TAG_END);
ng.ng_LeftEdge =300;
ng.ng_TopEdge +=14;
ng.ng_GadgetText ="P";
ng.ng_GadgetID ++;
gad= CreateGadget(BUTTON_KIND,gad,&ng,TAG_END);
ng.ng_LeftEdge +=18 ;
ng.ng_GadgetText ="Q";
ng.ng_GadgetID ++;
gad= CreateGadget(BUTTON_KIND,gad,&ng,TAG_END);
ng.ng_LeftEdge +=18 ;
ng.ng_GadgetText ="R";
ng.ng_GadgetID ++;
gad= CreateGadget(BUTTON_KIND,gad,&ng,TAG_END);
ng.ng_LeftEdge +=18 ;
ng.ng_GadgetText ="S";
ng.ng_GadgetID ++;
gad= CreateGadget(BUTTON_KIND,gad,&ng,TAG_END);
ng.ng_LeftEdge +=18 ;
ng.ng_GadgetText ="T";
ng.ng_GadgetID ++;
gad= CreateGadget(BUTTON_KIND,gad,&ng,TAG_END);
ng.ng_LeftEdge =300;
ng.ng_TopEdge +=14;
ng.ng_GadgetText ="U";
ng.ng_GadgetID ++;
gad= CreateGadget(BUTTON_KIND,gad,&ng,TAG_END);
ng.ng_LeftEdge +=18 ;
ng.ng_GadgetText ="V";
ng.ng_GadgetID ++;
gad= CreateGadget(BUTTON_KIND,gad,&ng,TAG_END);
ng.ng_LeftEdge +=18 ;
ng.ng_GadgetText ="W";
ng.ng_GadgetID ++;
gad= CreateGadget(BUTTON_KIND,gad,&ng,TAG_END);
ng.ng_LeftEdge +=18 ;
ng.ng_GadgetText ="X";
ng.ng_GadgetID ++;
gad= CreateGadget(BUTTON_KIND,gad,&ng,TAG_END);
ng.ng_LeftEdge +=18 ;
ng.ng_GadgetText ="Y";
ng.ng_GadgetID ++;
gad= CreateGadget(BUTTON_KIND,gad,&ng,TAG_END);
ng.ng_LeftEdge =300;
ng.ng_TopEdge +=14;
ng.ng_GadgetText ="Z";
ng.ng_GadgetID ++;
gad= CreateGadget(BUTTON_KIND,gad,&ng,TAG_END);
ng.ng_LeftEdge +=18;
ng.ng_GadgetText ="?";
ng.ng_GadgetID ++;
gad= CreateGadget(BUTTON_KIND,gad,&ng,TAG_END);
ng.ng_LeftEdge +=18 ;
ng.ng_Width =54;
ng.ng_GadgetText ="ADD";
ng.ng_GadgetID ++;
gad= CreateGadget(BUTTON_KIND,gad,&ng,TAG_END);
ng.ng_TopEdge +=14;
ng.ng_Width =54;
ng.ng_GadgetText ="QUIT";
ng.ng_GadgetID ++;
gad= CreateGadget(BUTTON_KIND,gad,&ng,TAG_END);
ng.ng_LeftEdge =10;
ng.ng_TopEdge =2+mysc->WBorTop+(mysc->Font->ta_YSize+1);
ng.ng_Width =180;
ng.ng_Height =12;
ng.ng_GadgetText ="BOOL 1";
ng.ng_GadgetID ++;
gad= CreateGadget(BUTTON_KIND,gad,&ng,TAG_END);
if (gad != NULL)
{
if ((mywin = OpenWindowTags(NULL,
WA_Title, "PhoneBook V1.0",
WA_Gadgets, glist, WA_AutoAdjust, TRUE,
WA_Width, 400, WA_InnerHeight, 100,
WA_DragBar, TRUE, WA_DepthGadget, TRUE,
WA_Activate, TRUE, WA_CloseGadget, TRUE,
WA_IDCMP, IDCMP_CLOSEWINDOW |
IDCMP_REFRESHWINDOW |
BUTTONIDCMP,
WA_PubScreen, mysc,
TAG_END)) != NULL)
{
GT_RefreshWindow(mywin,NULL);
process_window_events(mywin);
CloseWindow(mywin);
}
}
FreeGadgets(glist);
FreeVisualInfo(vi);
}
UnlockPubScreen(NULL,mysc);
} }
VOID process_window_events(struct Window *mywin) { struct IntuiMessage
*imsg; ULONG class; UWORD code; struct Gadget *gad;
while (!terminated)
{
Wait(1<< mywin->UserPort->mp_SigBit);
while ((!terminated) && (imsg = GT_GetIMsg(mywin->UserPort)))
{
gad = (struct Gadget *)imsg->IAddress;
class=imsg->Class;
code =imsg->Code;
switch (class)
{
case IDCMP_GADGETUP:
Do_Gad(mywin,gad,code);
break;
case IDCMP_CLOSEWINDOW:
terminated = TRUE;
break;
case IDCMP_REFRESHWINDOW:
GT_BeginRefresh(mywin);
GT_EndRefresh(mywin,TRUE);
break;
}
GT_ReplyIMsg(imsg);
}
} } VOID Do_Gad(struct Window *mywin,struct Gadget *gad,UWORD code) {
switch(gad->GadgetID)
{
case 1:printf("A\n");
break;
case 2:printf("B\n");
break;
case 3:printf("C\n");
break;
case 4:printf("D\n");
break;
case 5:printf("E\n");
break;
case 6:printf("F\n");
break;
case 7:printf("G\n");
break;
case 8:printf("H\n");
break;
case 9:printf("I\n");
break;
case 10:printf("J\n");
break;
case 11:printf("K\n");
break;
case 12:printf("L\n");
break;
case 13:printf("M\n");
break;
case 14:printf("N\n");
break;
case 15:printf("O\n");
break;
case 16:printf("P\n");
break;
case 17:printf("Q\n");
break;
case 18:printf("R\n");
break;
case 19:printf("S\n");
break;
case 20:printf("T\n");
break;
case 21:printf("U\n");
break;
case 22:printf("V\n");
break;
case 23:printf("W\n");
break;
case 24:printf("X\n");
break;
case 25:printf("Y\n");
break;
case 26:printf("Z\n");
break;
case 29:printf("TERMINATE\n");
terminated = TRUE;
break;
} }
// End C Code
某些程式碼依賴於使用偽造(非 boopsi)元件的 gadtools 庫的 AOS 實現,其中尤其是在更復雜的元件(列表檢視)中,大多陣列件(輸入)處理都在 GT_GetImsg/GT_FitlerImsg() 函式中完成。在 AROS gadtools 庫中使用真正的 boopsi 元件,因此行為有所不同。
struct Gadget *CreateGadgetA(ULONG kind, struct Gadget *previous, struct NewGadget *ng, struct TagItem *taglist) void FreeGadgets(struct Gadget *glist) void GT_SetGadgetAttrsA(struct Gadget *gad, struct Window *win, struct Requester *req, struct TagItem *tagList) struct Menu *CreateMenusA(struct NewMenu *newmenu, struct TagItem *tagList) void FreeMenus(struct Menu *menu) BOOL LayoutMenuItemsA(struct MenuItem *menuitem, APTR vi, struct TagItem *tagList) BOOL LayoutMenusA(struct Menu *menu, APTR vi, struct TagItem *tagList) struct IntuiMessage *GT_GetIMsg(struct MsgPort *intuiport) void GT_ReplyIMsg(struct IntuiMessage *imsg) void GT_RefreshWindow(struct Window *win, struct Requester *req) void GT_BeginRefresh(struct Window *win) void GT_EndRefresh(struct Window *win, BOOL complete) struct IntuiMessage *GT_FilterIMsg(struct IntuiMessage *imsg) struct IntuiMessage *GT_PostFilterIMsg(struct IntuiMessage *modimsg) struct Gadget *CreateContext(struct Gadget **glistpointer) void DrawBevelBoxA(struct RastPort *rport, WORD left, WORD top, WORD width, WORD height, struct TagItem *taglist) APTR GetVisualInfoA(struct Screen *screen, struct TagItem *tagList) void FreeVisualInfo(APTR vi) LONG GT_GetGadgetAttrsA(struct Gadget *gad, struct Window *win, struct Requester *req, struct TagItem *taglist)
每個選項中的前幾個專案可以在建立後進行更改。
GA_Immediate 和 GA_RelVerify 是標籤,GACT_IMMEDIATE 和 GACT_RELVERIFY 是用於 struct Gadget 的 Activation 欄位的標誌。
CreateGadgetA Taglists
GT_Underscore - 指示在要加下劃線的元件標籤中字元之前的符號。這可以用來指示元件的鍵盤等效項(請注意,GadTools 不會處理鍵 - 只顯示下劃線)。
BUTTON_OPTION(操作按鈕)
GA_Disabled (BOOL) - Set to TRUE to disable gadget, FALSE otherwise (default FALSE). GA_Immediate (BOOL) - Hear IDCMP_GADGETDOWN events from button gadget (default FALSE).
CHECKBOX_OPTION(開/關專案)
GA_Disabled (BOOL) - Set to TRUE to disable gadget, FALSE otherwise (default FALSE). GTCB_Checked (BOOL) - Initial state of checkbox (default FALSE) GTCB_Scaled (BOOL) - If true, then checkbox imagery will be scaled to fit the gadget's width & height. Otherwise, a fixed size of CHECKBOXWIDTH by CHECKBOXHEIGHT will be used. (default FALSE)
CYCLEOPTION(多狀態選擇)
GA_Disabled (BOOL) - Set to TRUE to disable gadget, FALSE otherwise (default FALSE). GTCY_Labels (STRPTR *) - Pointer to NULL-terminated array of strings that are the choices offered by the cycle gadget. This tag is required. GTCY_Active (UWORD) - The ordinal number (counting from zero) of the initially active choice of a cycle gadget (default zero).
INTEGER_OPTION(數字輸入)
GA_Disabled (BOOL) - Set to TRUE to disable gadget, FALSE otherwise (default FALSE). GTIN_Number (LONG) - The initial contents of the integer gadget (default 0). GA_Immediate (BOOL) - Hear IDCMP_GADGETDOWN events from integer gadget (default FALSE). GA_TabCycle (BOOL) - Set to TRUE so that pressing or will activate the next or previous such gadget. (default TRUE). GTIN_MaxChars (UWORD) - The maximum number of digits that the integer gadget is to hold (defaults to 10). GTIN_EditHook (struct Hook *) - Hook to use as a custom integer gadget edit hook (StringExtend->EditHook) for this gadget. GadTools will allocate the StringExtend->WorkBuffer for you. (default NULL). STRINGA_ExitHelp (BOOL) - Set to TRUE to have the help-key cause an exit from the integer gadget. You will then receive an IDCMP_GADGETUP event with Code = 0x5F (rawkey for help). (default FALSE) STRINGA_Justification - Controls the justification of the contents of an integer gadget. Choose one of STRINGLEFT, STRINGRIGHT, or STRINGCENTER (defaults to STRINGLEFT). STRINGA_ReplaceMode (BOOL) - If TRUE, this integer gadget is in replace-mode (default FALSE (insert-mode)).
LISTVIEW_OPTION(滾動列表)
GA_Disabled (BOOL) - Set to TRUE to disable gadget, FALSE otherwise (default FALSE). GTLV_Top (WORD) - Top item visible in the listview. This value will be made reasonable if out-of-range (default 0). GTLV_Labels (struct List *) - List of nodes whose ln_Name fields are to be displayed in the listview. GTLV_Selected (UWORD) - Ordinal number of currently selected item, or 0 to have no current selection (default 0). GTLV_MakeVisible (WORD) - Number of an item that should be forced within the visible area of the listview by doing minimal scrolling. This tag overrides GTLV_Top. GTLV_ReadOnly (BOOL) - If TRUE, then listview is read-only (default FALSE). GTLV_ScrollWidth (UWORD) - Width of scroll bar for listview. Must be greater than zero (default 16). GTLV_ShowSelected (struct Gadget *) - NULL to have the currently selected item displayed beneath the listview under V37 or with a highlight bar in V39. If not NULL, this is a pointer to an already-created GadTools STRING_KIND gadget to have an editable display of the currently selected item. If the tag is not present, the currently selected item will not be displayed. LAYOUTA_Spacing (UWORD) - Extra space to place between lines of listview (default 0). GTLV_ItemHeight (UWORD) - The exact height of an item. This is normally useful for listviews that use the GTLV_CallBack rendering hook (defaults to ng->ng_TextAttr->ta_YSize). GTLV_CallBack (struct Hook *) - Callback hook for various listview operations. Only callback supported is for custom rendering of individual items in the listview. The call back hook is called with: A0 - struct Hook * A1 - struct LVDrawMsg * A2 - struct Node * The callback hook *must* check the lvdm_MethodID field of the message and only do processing if it equals LV_DRAW. If any other value is passed, the callback hook must return LVCB_UNKNOWN GTLV_MaxPen (UWORD) - The maximum pen number used by rendering in a custom rendering callback hook. This is used to optimize the rendering and scrolling of the listview display (default being the maximum pen number used by all of TEXTPEN, BACKGROUNDPEN, FILLPEN, TEXTFILLPEN, and BLOCKPEN.
MX_OPTION(互斥,單選按鈕)
GA_Disabled (BOOL) - Set to TRUE to disable gadget, FALSE otherwise (default FALSE). GTMX_Active (UWORD) - The ordinal number (counting from zero) of the initially active choice of an mx gadget (default 0). GTMX_Labels (STRPTR *) - Pointer to a NULL-terminated array of strings which are to be the labels beside each choice in a set of mutually exclusive gadgets. This tag is required GTMX_Spacing (UWORD) - The amount of space between each choice of a set of mutually exclusive gadgets. This amount is added to the font height to produce the vertical shift between choices (default 1). GTMX_Scaled (BOOL) - If true, then mx gadget imagery will be scaled to fit the gadget's width & height. Otherwise, a fixed size of MXWIDTH by MXHEIGHT will be used. When setting this tag to TRUE, should typically set the height of the gadget to be (ng.ng_TextAttr->ta_YSize + 1). (default FALSE.) GTMX_TitlePlace - One of PLACETEXT_LEFT, PLACETEXT_RIGHT, PLACETEXT_ABOVE, or PLACETEXT_BELOW, indicating where the title of the gadget is to be displayed. Without this tag, the NewGadget.ng_GadgetText field is ignored for MX_OPTION gadgets. LAYOUTA_Spacing - FOR COMPATIBILITY ONLY. Use GTMX_Spacing instead. The number of extra pixels to insert between each choice of a mutually exclusive gadget. This is added to the present gadget image height (9) to produce the true spacing between choices. (default FontHeight-8, which is zero for 8-point font users).
NUMBER_OPTION(只讀數字)
GTNM_Number (LONG) - A signed long integer to be displayed as a read-only number (default 0). GTNM_Border (BOOL) - If TRUE, this flag asks for a recessed border to be placed around the gadget. GTNM_FrontPen (UBYTE) - The pen to use when rendering the number (default DrawInfo->dri_Pens[TEXTPEN]). GTNM_BackPen (UBYTE) - The pen to use when rendering the background of the number (defaults to leaving the background untouched). GTNM_Justification (UBYTE) - Determines how the number is rendered within the gadget box. GTJ_LEFT will make the rendering be flush with the left side of the gadget, GTJ_RIGHT will make it flush with the right side, and GTJ_CENTER will center the number within the gadget box. (default GTJ_LEFT). GTNM_Format (STRPTR) - C-Style formatting string to apply on the number before display. Be sure to use the 'l' (long) modifier. This string is processed using exec.library/RawDoFmt(), so refer to that function for details. (default "%ld") GTNM_MaxNumberLen (ULONG) - Maximum number of bytes that can be generated by applying the GTNM_Format formatting string to the number (excluding the NULL terminator). (default 10). GTNM_Clipped (BOOL) - Determine whether text should be clipped to the gadget dimensions (defaults to FALSE for gadgets without borders, TRUE for gadgets with borders).
PALETTE_OPTION(顏色選擇)
GA_Disabled (BOOL) - Set to TRUE to disable gadget, FALSE otherwise (default FALSE). GTPA_Color (UBYTE) - Initially selected color of the palette. This number is a pen number, and not the ordinal color number within the palette gadget itself. (default 1). GTPA_ColorOffset (UBYTE) - First color to use in palette (default 0). GTPA_ColorTable (UBYTE *) - Pointer to a table of pen numbers indicating which colors should be used and edited by the palette gadget. This array must contain as many entries as there are colors displayed in the palette gadget. The array provided with this tag must remain valid for the life of the gadget or until a new table is provided. (default NULL, which causes a 1-to-1 mapping of pen numbers). GTPA_Depth (UWORD) - Number of bitplanes in the palette (default 1). GTPA_IndicatorWidth (UWORD) - The desired width of the current-color indicator, if you want one to the left of the palette. GTPA_IndicatorHeight (UWORD) - The desired height of the current-color indicator, if you want one above the palette. GTPA_NumColors (UWORD) - Number of colors to display in the palette gadget. This override GTPA_Depth and allows numbers which are not powers of 2. (default 2)
SCROLLER_OPTION(用於在區域或列表中滾動)
GA_Disabled (BOOL) - Set to TRUE to disable gadget, FALSE otherwise (default FALSE). GTSC_Top (WORD) - Top visible in area scroller represents (default 0). GTSC_Total (WORD) - Total in area scroller represents (default 0). GTSC_Visible (WORD) - Number visible in scroller (default 2). GA_RelVerify (BOOL) - Hear every IDCMP_GADGETUP event from scroller (default FALSE). GA_Immediate (BOOL) - Hear every IDCMP_GADGETDOWN event from scroller (default FALSE). GTSC_Arrows (UWORD) - Asks for arrows to be attached to the scroller. The value supplied will be taken as the width of each arrow button for a horizontal scroller, or the height of each button for a vertical scroller (the other dimension will match the whole scroller). PGA_Freedom - Whether scroller is horizontal or vertical. Choose LORIENT_VERT or LORIENT_HORIZ (default LORIENT_HORIZ).
SLIDER_OPTION(指示級別或強度)
GA_Disabled (BOOL) - Set to TRUE to disable gadget, FALSE otherwise (default FALSE). GTSL_Min (WORD) - Minimum level for slider (default 0). GTSL_Max (WORD) - Maximum level for slider (default 15). GTSL_Level (WORD) - Current level of slider (default 0). GA_RelVerify (BOOL) - If you want to hear each slider IDCMP_GADGETUP event (default FALSE). GA_Immediate (BOOL) - If you want to hear each slider IDCMP_GADGETDOWN event (default FALSE). GTSL_MaxLevelLen (UWORD) - Maximum length in characters of level string when rendered beside slider (default 2). GTSL_LevelFormat (STRPTR) - C-Style formatting string for slider level. Be sure to use the 'l' (long) modifier. This string is processed using exec.library/RawDoFmt(), so refer to that function for details. (default "%ld"). GTSL_LevelPlace - One of PLACETEXT_LEFT, PLACETEXT_RIGHT, PLACETEXT_ABOVE, or PLACETEXT_BELOW, indicating where the level indicator is to go relative to slider (default to PLACETEXT_LEFT). GTSL_DispFunc ( LONG (*function)(struct Gadget *, WORD) ) - To calculate level to be displayed. A number-of-colors slider might want to set the slider up to think depth, and have a (1 << n) function here. No Default Your function must take a pointer to gadget as the first parameter, the level (a WORD) as the second, and return the result as a LONG. GTSL_MaxPixelLen (ULONG) - Indicates the maximum pixel size used up by the level display for any value of the slider. This is mostly useful when dealing with proportional fonts. (default FontWidth*MaxLevelLen). GTSL_Justification (UBYTE) - Determines how the level display is to be justified within its alotted space. Choose one of GTJ_LEFT, GTJ_RIGHT, or GTJ_CENTER (default GTJ_LEFT). PGA_Freedom - Set to LORIENT_VERT or LORIENT_HORIZ to have a vertical or horizontal slider (defaults to LORIENT_HORIZ).
STRING_OPTION(文字輸入)
GA_Disabled (BOOL) - Set to TRUE to disable gadget, FALSE otherwise (default FALSE). GTST_String (STRPTR) - The initial contents of the string gadget, or NULL (default) if string is to start empty. GA_Immediate (BOOL) - Hear IDCMP_GADGETDOWN events from string gadget (default FALSE). GA_TabCycle (BOOL) - Set to TRUE so that pressing or will activate the next or previous such gadget. (defaults to TRUE, unlike regular Intuition string gadgets which default FALSE). GTST_MaxChars (UWORD) - The maximum number of characters that the string gadget is to hold. GTST_EditHook (struct Hook *) - Hook to use as a custom string gadget edit hook (StringExtend->EditHook) for this gadget. GadTools will allocate the StringExtend->WorkBuffer for you. (default NULL). STRINGA_ExitHelp (BOOL) - Set to TRUE to have the help-key cause an exit from the string gadget. You will then receive an IDCMP_GADGETUP event with Code = 0x5F (rawkey for help). STRINGA_Justification - Controls the justification of the contents of a string gadget. Choose one of STRINGLEFT, STRINGRIGHT, or STRINGCENTER (default STRINGLEFT). STRINGA_ReplaceMode (BOOL) - If TRUE, this string gadget is in replace-mode (defaults to FALSE (insert-mode)).
TEXT_OPTION(只讀文字)
GTTX_Text - Pointer to a NULL terminated string to be displayed, as a read-only text-display gadget, or NULL. (default NULL) GTTX_CopyText (BOOL) - This flag instructs the text-display gadget to copy the supplied text string, instead of using only pointer to the string. This only works for the initial value of GTTX_Text set at CreateGadget() time. If you subsequently change GTTX_Text, the new text will be referenced by pointer, not copied. Do not use this tag with a NULL GTTX_Text. GTTX_Border (BOOL) - If TRUE, this flag asks for a recessed border to be placed around the gadget. GTTX_FrontPen (UBYTE) - The pen to use when rendering the text (default DrawInfo->dri_Pens[TEXTPEN]). GTTX_BackPen (UBYTE) - The pen to use when rendering the background of the text (defaults to leaving the background untouched). GTTX_Justification (UBYTE) - Determines how the text is rendered within the gadget box. GTJ_LEFT will make the rendering be flush with the left side of the gadget, GTJ_RIGHT will make it flush with the right side, and GTJ_CENTER will center the text within the gadget box. (default GTJ_LEFT). GTTX_Clipped (BOOL) - Determine whether text should be clipped to the gadget dimensions (defaults to FALSE for gadgets without borders, TRUE for gadgets with borders).
LayoutGadgetTags
GTMN_Menu (struct Menu *) - Pointer to the Menu structure whose FirstItem is the MenuItem supplied. If the menu items are such that they need to be columnized or shifted, the Menu structure is needed to perform the complete calculation. For the following tags, please see the description under LayoutMenusA(). Their behavior is identical when used in LayoutMenuItemsA(). GTMN_TextAttr GTMN_NewLookMenus GTMN_Checkmark GTMN_AmigaKey GTMN_FrontPen
嘗試在控制檯程式碼(用於選單)中手動開啟 gadtools。我需要手動開啟它,因為它*將*在引導外殼中失敗(見下文),因此我需要處理它不可用的情況。在我看來,在引導期間自動開啟非駐留庫是一個非常糟糕的主意……如果關閉它,很多東西都會壞掉嗎?或者,是否存在一種方法可以逐個案例地防止自動開啟?據我所知,您只需要手動宣告基本指標。這將阻止從 libautoinit 獲取它(以及相關的庫開啟程式碼)。對於程式,它有效。我認為它對駐留程式有效。autoinit 程式碼由 libbase 變數連結。例如,autoinit 程式碼定義了庫的全域性 libbase 變數。如果在程式碼中的某個地方將“struct Library *GadToolsBase”定義為全域性變數,則不會連結 autoinit 程式碼。請僅在確實需要時使用它,並新增適當的註釋說明為什麼需要它。此處的具體情況是避免在控制檯程式碼中複製大量來自 gadtools 的選單佈局程式碼,以將選單新增到控制檯視窗,而無需將 gadtools 連結到核心。這意味著引導外殼將無法獲得選單,但我認為與使事情變得非常混亂相比,這是一個相當公平的權衡。
而且它只在全域性庫基址被使用時才會被呼叫,對於可移動程式碼來說不應該如此,是嗎?這是我沒有考慮到的。如果我宣告一個全域性 GadToolsBase,我是否會弄亂一些東西,或者 bss 是否被正確處理?如果它弄亂了事情,是否有其他方法可以防止自動開啟?(提交了控制檯處理程式的基本選單結構,該結構使用全域性 GadToolsBase)。
實際上,它不是最佳的,因為在 m68k 上,.bss 的唯一“已知始終存在”的記憶體位於晶片 RAM 中,晶片 RAM 既寶貴又慢(由於與影片和音訊操作的爭用)。對於此用法,它可能沒問題,但如果您能找到一種方法將其分配到控制檯處理程式傳遞的結構(con_base?)中並從那裡取消引用它,這可能是一種更好的方法。AllocMem() 記憶體從最高優先順序開始分配。請參閱 rom/devs/filesys/AmberRAM/handler.h 的“struct Handler”,以及緊隨其後的宏,瞭解如何執行此操作的示例。控制檯處理程式已經在其處理程式資料結構中放置了許多內容,因此如果有一種方法可以抑制自動開啟而無需使用全域性變數,那麼將其放在那裡非常簡單。
在 NEWWINDOWSIZE 事件期間,是否有某個地方提供關於所有需要處理事項的良好參考?你可能已經知道,但與 SIZEVERIFY 不同,NEWWINDOWSIZE 不會像 ReplyMsg() 一樣阻塞。
位元組序問題
程式碼中可能存在方法結構體,它使用 WORD 作為某些(座標)欄位,然後在呼叫該方法時執行類似 gDoClassMethod(... , (x << 16) | (y & 0xffff), ...)。這依賴於大端位元組序,因此在 x86 上會失敗。