#define INTERIM_MENU (isMenuBar || interim)
//#define INTERIM_MENU interim
-static int strcmpTillTab(char * a, char * b)
+static int strcmpTillTab(const char * a, const char * b)
{
if(a && !b) return 1;
else if(b && !a) return -1;
if(menu)
menu.RemoveItem(this);
if(value)
- value.AddItem(this);
+ value.AddItem(this);
}
}
};
- property char * text
+ property const char * text
{
set
{
if(copyText)
{
- delete text;
+ delete (char *)text;
text = CopyString(value);
}
else
set
{
accelerator = value;
-
+
if(!manualAccelText && text)
{
char accelString[50] = "\t";
char * tabPos;
int length = 0;
- if(value.ctrl) strcat(accelString, "Ctrl+");
- if(value.alt) strcat(accelString, "Alt+");
- if(value.shift) strcat(accelString, "Shift+");
+ if(value.ctrl) strcat(accelString, $"Ctrl+");
+ if(value.alt) strcat(accelString, $"Alt+");
+ if(value.shift) strcat(accelString, $"Shift+");
if(value.code == k0)
strcat(accelString, "0");
else if(value.code >= k1 && value.code <= k9)
{
- accelString[strlen(accelString)] = '1' + (char)(value.code - k1);
+ accelString[strlen(accelString)] = (char)('1' + value.code - k1);
accelString[strlen(accelString)+1] = 0;
}
else
Key accel = value.code;
bool needClass = false;
char tempString[50];
- char * result = accel.OnGetString(tempString, null, &needClass);
+ const char * result = accel.OnGetString(tempString, null, &needClass);
int len = strlen(accelString);
if(result) strcpy(accelString + len, result);
// accelString[len] = toupper(accelString[len]);
memcpy(newText, text, length);
newText[length] = 0;
strcat(newText, accelString);
- if(copyText) delete text;
+ if(copyText) delete (void *)text;
text = newText;
copyText = true;
}
}
// Should callback be called here? guess not ;)
}
- get { return checked; }
+ get { return checked; }
};
property bool disabled { set { if(this) disabled = value; } };
property bool checkable { set { checkable = value; } };
property bool isRadio { set { radio = value; } };
- property uint id { set { id = value; } get { return id; } };
+ property uint64 id { set { id = value; } get { return id; } };
property BitmapResource bitmap
{
set
{
+ delete bitmaps[0];
+ delete bitmaps[1];
+ delete bitmaps[2];
bitmaps[0] = value;
- bitmaps[1] = BitmapResource { fileName = value.fileName, monochrome = true };
- bitmaps[2] = BitmapResource { fileName = value.fileName, grayed = true };
+ bitmaps[1] = value ? (value.alphaBlend ? value : { fileName = value.fileName, monochrome = true }) : null;
+ bitmaps[2] = value ? { fileName = value.fileName, grayed = true } : null;
+ if(value)
+ {
+ incref bitmaps[0];
+ incref bitmaps[1];
+ incref bitmaps[2];
+ }
}
+ get { return bitmaps[0]; }
};
property bool copyText
{
}
else
{
- if(text && copyText)
- delete text;
+ if(copyText)
+ delete (void *)text;
}
copyText = value;
}
bool isDivider;
bool placement;
- uint id;
+ uint64 id;
Key hotKey;
Key accelerator;
- char * text;
+ const char * text;
BitmapResource bitmaps[3];
bool checkable, radio;
bool checked;
{
if(copyText)
// delete ITEM_TEXT(this);
- delete text;
+ delete (void *)text;
delete subMenu;
+ delete bitmaps[0];
+ delete bitmaps[1];
+ delete bitmaps[2];
}
};
{
MenuPlacement()
{
- placement = true;
+ placement = true;
}
public:
/*
property Menu parent { set {} };
- property char * text { set {} };
+ property const char * text { set {} };
property Key hotKey { set {} };
*/
};
item.menu = this;
}
}
-
+
void RemoveItem(MenuItem item)
{
if(item.menu == this)
MenuItem menuItem { };
ItemPtr ptr { item = menuItem };
items.Add(ptr);
-
+
incref menuItem;
itemCount++;
}
}
}
-
+
void AddDynamic(MenuItem addedItem, Window master, bool persistent)
{
if(addedItem)
{
ItemPtr ptr = null, oldItemPtr;
-
+
for(oldItemPtr = items.first; oldItemPtr; oldItemPtr = oldItemPtr.next)
{
if((oldItemPtr.item.subMenu || oldItemPtr.item.placement) && !strcmpTillTab(ITEM_TEXT(oldItemPtr.item), ITEM_TEXT(addedItem)))
addedItem.menu = this;
}
}
-
- MenuItem FindItem(bool (* Window::notifySelect)(MenuItem selection, Modifiers mods), uint id)
+
+ MenuItem FindItem(bool (* Window::notifySelect)(MenuItem selection, Modifiers mods), uint64 id)
{
ItemPtr ptr;
-
+
for(ptr = items.first; ptr; ptr = ptr.next)
{
MenuItem item = ptr.item;
ptr.item = ptr.oldItem;
ptr.oldItem = null;
delete ptr.item;
- }
+ }
items.Delete(ptr);
}
}
for(mergeIntoItemPtr = items.first; mergeIntoItemPtr; mergeIntoItemPtr = mergeIntoItemPtr.next)
{
MenuItem mergeIntoItem = mergeIntoItemPtr.item;
- if(/*!mergeIntoItem.subMenu && /*mergeIntoItem.placement && !mergeIntoItemPtr.inserted && */!strcmpTillTab(ITEM_TEXT(mergeIntoItem), ITEM_TEXT(beingMergedItem)))
+ if(/*!mergeIntoItem.subMenu && /-*mergeIntoItem.placement && !mergeIntoItemPtr.inserted && */!strcmpTillTab(ITEM_TEXT(mergeIntoItem), ITEM_TEXT(beingMergedItem)))
{
//if(!beingMergedItem.placement || beingMergedItemPtr.inserted)
{
itemCount++;
}
}
-
- if(!beingMergedItem.isDivider || (previous.item && !previous.item.isDivider))
+
+ if(!beingMergedItem.isDivider || !previous || (previous.item && !previous.item.isDivider))
{
mergeIntoItemPtr = ItemPtr { };
items.Insert(previous, mergeIntoItemPtr);
}
else if(item.subMenu)
item.subMenu.Clean(window);
-
+
if(ptr.inserted.deleteItem)
delete item;
}
}
- Menu FindMenu(char * name)
+ Menu FindMenu(const char * name)
{
ItemPtr ptr;
-
+
for(ptr = items.first; ptr; ptr = ptr.next)
{
MenuItem item = ptr.item;
}
property Menu parent { set { if(value) value.AddSubMenu(this); } };
- property char * text { set { text = value; /* CopyString(value);*/ } };
+ property const char * text { set { text = (char *)value; /* CopyString(value);*/ } };
property Key hotKey { set { hotKey = value; } };
+ property bool hasMargin { set { hasMargin = value; } };
private:
OldList items;
int itemHeight;
int itemCount;
bool mergeClients;
+ bool hasMargin;
Menu()
{
int rw, rh;
int totalHeight;
Menu menu;
- ItemPtr selected;
+ ItemPtr selected;
bool pressed;
bool altDown;
bool keyboardFocus;
bool mouseInput;
Time unpressedTime;
-
- void (* FontExtent)(Display display, Font font, char * text, int len, int * width, int * height);
+
+ void (* FontExtent)(Display display, Font font, const char * text, int len, int * width, int * height);
FontResource boldFont { faceName = font.faceName, font.size, bold = true, window = this };
BitmapResource subArrow { fileName = "<:ecere>elements/arrowRight.png", window = this };
{
bool result;
PopupMenu window = this, master;
- PopupMenu popupMenu;
for(; (master = (PopupMenu)window.master); window = master)
{
{
ItemPtr selected, current = this.selected;
for(selected = (current && current.prev) ? current.prev : menu.items.last;
- selected &&
- (selected.item.isDivider || selected.item.placement || ITEM_DISABLED(selected.item)) &&
+ selected &&
+ (selected.item.isDivider || selected.item.placement || ITEM_DISABLED(selected.item)) &&
selected != current;
selected = selected.prev ? selected.prev : menu.items.last)
{
{
ItemPtr selected, current = this.selected;
for(selected = (current && current.next) ? current.next : menu.items.first;
- selected &&
- (selected.item.isDivider || selected.item.placement || ITEM_DISABLED(selected.item)) &&
+ selected &&
+ (selected.item.isDivider || selected.item.placement || ITEM_DISABLED(selected.item)) &&
selected != current;
selected = selected.next ? selected.next : menu.items.first)
{
Window parent = this.parent;
Window activeClient = parent.activeClient;
bool systemButtons = activeClient && activeClient.state == maximized;
-
+
keyboardFocus = true;
pressed = true;
int y = 0;
int selectedY = 0;
ItemPtr ptr;
-
+
for(ptr = menu.items.first; ptr; ptr = ptr.next)
{
MenuItem item = ptr.item;
if(item.placement) continue; //&& !ptr.inserted) continue;
if(selected == ptr)
{
-
+
selectedY = y;
break;
}
MenuItem selection = selectionPtr.item;
if(!ITEM_DISABLED(selection))
{
- Window master = this;
+ Window master = this;
if(!isMenuBar)
master = master.master;
master = selectionPtr.master;
while(eClass_IsDerived(master._class, _class) && master.master)
master = master.master;
-
+
if(selection.checkable)
selection.checked = !selection.checked;
else if(selection.radio)
MenuItem item = ptr.item;
if(item.subMenu)
{
- if(!CheckAccelerators(item.subMenu, key))
+ if(!CheckAccelerators(item.subMenu, key))
return false;
}
else if(!item.isDivider)
Menu menu = this.menu;
// Mouse moved inside menu
ItemPtr selected = null;
-
+
*selectedX = 0;
*selectedY = 0;
if(!helpBreak)
{
ItemPtr nextPtr;
-
+
int breakX = clientSize.w - (systemButtons ? 48 : 0);
for(nextPtr = ptr.next; nextPtr; nextPtr = nextPtr.next)
{
}
else
{
- char * text = ITEM_TEXT(item);
+ const char * text = ITEM_TEXT(item);
FontExtent(display, fontObject, text, text ? strlen(text) : 0, &len, null);
if((mx >= x - 16 && mx < x + len + 16))
{
// Window Overrides
void OnRedraw(Surface surface)
{
+ bool hasMargin = menu ? menu.hasMargin : false;
int x = 0;
int y = 0;
int height;
Window activeClient = parent.activeClient;
bool systemButtons = activeClient && activeClient.state == maximized;
int bitmapOffset = 0;
+ bool hasBitmap = false;
+ bool isRadio = false;
surface.TextFont(fontObject);
surface.TextExtent(" ", 1, null, &height);
if(!isMenuBar)
{
+ if(menu)
+ {
+ ItemPtr ptr;
+ for(ptr = menu.items.first; ptr; ptr = ptr.next)
+ {
+ if(ptr.item.bitmaps[0])
+ {
+ hasBitmap = true;
+ break;
+ }
+ }
+
+ for(ptr = menu.items.first; ptr; ptr = ptr.next)
+ {
+ if(ptr.item.radio)
+ {
+ isRadio = true;
+ break;
+ }
+ }
+ }
+
if(guiApp.textMode)
bitmapOffset = 16;
else
- bitmapOffset = 12;
+ bitmapOffset = hasMargin ? 27 : (hasBitmap ? 18 : 12);
+ if(hasBitmap && isRadio)
+ bitmapOffset += 18;
}
else if(guiApp.textMode)
bitmapOffset = 8;
else
{
// Shiny gradient for menu bar
- ColorKey keys[2] =
+ ColorKey keys[2] =
{
{ white, 0 },
{ popupMenuColor, 1 }
surface.Area(0,y,clientSize.w-1,y+rh-1);
}
else
- surface.Area(2,y,clientSize.w-3,y+rh);
+ surface.Area(/*(hasMargin ? bitmapOffset : 0) +*/ 2,y,clientSize.w-3,y+rh);
}
else
{
}
else
{
- surface.SetForeground(Color { 85, 85, 85 });
- surface.HLine(x + 2, x + rw - 5, y + (DIVIDER_HEIGHT) / 2);
- surface.SetForeground(white);
- surface.HLine(x + 2, x + rw - 5, y + (DIVIDER_HEIGHT) / 2 + 1);
+ int start = x + hasMargin ? bitmapOffset : 2;
+ int end = x + rw - (hasMargin ? 13 : 5);
+ surface.foreground = Color { 85, 85, 85 };
+ surface.HLine(start, end, y + (DIVIDER_HEIGHT) / 2);
+ surface.foreground = white;
+ surface.HLine(start, end, y + (DIVIDER_HEIGHT) / 2 + 1);
}
}
}
{
Bitmap icon = bitmap.bitmap;
if(icon)
- surface.Blit(icon, x + 3, y + (rh - icon.height)/2, 0,0, icon.width, icon.height);
+ surface.Blit(icon, x + (isRadio ? 18 : 0) + (hasMargin ? 5 : 3), y + (rh - icon.height)/2, 0,0, icon.width, icon.height);
}
if(item.bold)
if(ITEM_DISABLED(item) && selected == ptr)
{
- surface.SetForeground(activeBorder);
+ surface.SetForeground(formColor);
Interface::WriteKeyedText(surface, x + bitmapOffset + 5,
textY, ITEM_TEXT(item), ITEM_HOTKEY(item));
}
else
Interface::WriteKeyedTextDisabled(surface, x + bitmapOffset + 5,
textY, ITEM_TEXT(item), ITEM_HOTKEY(item), ITEM_DISABLED(item));
- surface.SetForeground(foreground);
+
+ // A nice vertical separation line
+ if(hasMargin && !isMenuBar)
+ {
+ surface.foreground = Color { 85, 85, 85 };
+ surface.VLine(clientArea.top, clientArea.bottom, x + bitmapOffset - 2);
+ surface.foreground = white;
+ surface.VLine(clientArea.top, clientArea.bottom, x + bitmapOffset - 1);
+ }
+ surface.foreground = foreground;
if(item.checked)
{
surface.DrawLine(x+5, y+9, x+8,y+12);
surface.VLine(y+(rh - 8)/2, y+(rh - 8)/2+7, clientSize.w-10);
surface.SetForeground(Color { 85, 85, 85 });
surface.DrawLine(clientSize.w-10, y+(rh - 8)/2, clientSize.w-4, y+rh / 2);
- surface.SetForeground(activeBorder);
+ surface.SetForeground(formColor);
surface.DrawLine(clientSize.w-10, y+(rh - 8)/2+7, clientSize.w-4, y+rh / 2);
*/
}
if(key && menu)
{
ItemPtr ptr;
-
+
for(ptr = menu.items.first; ptr; ptr = ptr.next)
{
MenuItem item = ptr.item;
if(MenuGoToNextItem())
Update(null);
result = false;
- }
+ }
break;
case end:
if(!isMenuBar)
if(MenuGoToPrevItem())
Update(null);
result = false;
- }
+ }
break;
case left:
if(isMenuBar)
if(key && menu)
{
//ItemPtr ptr;
-
+
if(ch >= 32 && !isMenuBar)
return false;
/*
{
ItemPtr ptr;
+ // Default width & height for merging menus into menu bars
+ if(isMenuBar)
+ {
+ FontExtent(display, font, "W",1, &maxW, &maxH);
+ if(!guiApp.textMode)
+ maxH += 6;
+ }
+
for(ptr = menu.items.first; ptr; ptr = ptr.next)
{
MenuItem item = ptr.item;
if(strstr(ITEM_TEXT(item), "\t"))
width += 8;
}
+ if(item.bitmap && item.radio)
+ width += 20;
if(item.subMenu) width += 20;
if(!guiApp.textMode)
height += 6;
if(item.bitmaps[1]) AddResource(item.bitmaps[1]);
if(item.bitmaps[2]) AddResource(item.bitmaps[2]);
}
- maxW += 24;
+ maxW += menu.hasMargin ? 32 : 24;
if(menu.text)
{
FontExtent(display, font,menu.text,strlen(menu.text),&width, &height);
if(this != masterMenuBar)
{
- if(!*w)
+ if(!*w)
*w = 80;
- if(!*h)
+ if(!*h)
*h = 20;
}
return true;
else
{
*x = Min(*x, parent.clientSize.w - w);
- *y = Min(*y, parent.clientSize.h - h);
+ *y = Min(*y, parent.clientSize.h - h);
}
if(parent == guiApp.desktop)
{
bool OnMouseMove(int mx, int my, Modifiers mods)
{
int selectedX, selectedY;
+ ItemPtr selected;
- ItemPtr selected = FindSelected(mx, my, &selectedX, &selectedY);
+ if(mods.isSideEffect) return true;
+
+ selected = FindSelected(mx, my, &selectedX, &selectedY);
if((!mods.isSideEffect || !this.selected) && (/*selected && */
selected != this.selected && (!selected || !ITEM_DISABLED(selected.item)) && (selected || !keyboardFocus)))
if(this.selected)
{
Menu childMenu = selected.item.subMenu;
-
+
this.pressed = pressed;
if(this.selected.item.subMenu)
{
if(isMenuBar)
{
- Time t = GetTime(), u = unpressedTime;
// Had to boost this to 0.1 for Windows Basic / XP theme / Remote Desktop
// Aero & Classic were fast enough for 0.01
if(GetTime() - unpressedTime < 0.1)
keyboardFocus = false;
Update(null);
}
- if(MenuItemSelection(menu, selected, (Key)mods))
+ if(MenuItemSelection(menu, selected, Key { modifiers = mods }))
return false;
}
}
{
Window master = this.master;
Window activeClient = master.activeClient;
+ // TOFIX: Fix need for a cast here...
+ while(activeClient && !((BorderBits)activeClient.borderStyle).fixed)
+ activeClient = activeClient.activeClient;
if(activeClient && activeClient.state == maximized)
activeClient.SetState(normal, false, mods);
}
break;
}
}
- if(destroy)
+ if(destroy)
{
if(MenuDestroyMasters(false))
return false;
}
}
}
+ get { return menu; }
};
property bool isMenuBar { set { isMenuBar = value; } };
property bool focus { get { return keyboardFocus; } };