linux build fixes

This commit is contained in:
Vadim Lopatin 2014-04-15 14:34:14 +04:00
parent f35b63ef95
commit 4ddccd9f6a
5 changed files with 383 additions and 377 deletions

View File

@ -179,6 +179,7 @@
<Compile Include="src\dlangui\widgets\tabs.d" />
<Compile Include="src\dlangui\graphics\resources.d" />
<Compile Include="src\dlangui\widgets\menu.d" />
<Compile Include="src\dlangui\widgets\popup.d" />
</ItemGroup>
<ItemGroup>
<Folder Include="src\dlangui\platforms\x11\" />

View File

@ -1,14 +1,14 @@
module dlangui.all;
public import dlangui.core.logger;
public import dlangui.core.types;
public import dlangui.platforms.common.platform;
public import dlangui.graphics.images;
public import dlangui.widgets.widget;
public import dlangui.widgets.controls;
public import dlangui.widgets.layouts;
public import dlangui.widgets.lists;
public import dlangui.widgets.tabs;
public import dlangui.widgets.menu;
public import dlangui.graphics.fonts;
public import dlangui.core.i18n;
module dlangui.all;
public import dlangui.core.logger;
public import dlangui.core.types;
public import dlangui.platforms.common.platform;
public import dlangui.graphics.images;
public import dlangui.widgets.widget;
public import dlangui.widgets.controls;
public import dlangui.widgets.layouts;
public import dlangui.widgets.lists;
public import dlangui.widgets.tabs;
public import dlangui.widgets.menu;
public import dlangui.graphics.fonts;
public import dlangui.core.i18n;

View File

@ -1,99 +1,99 @@
module dlangui.core.types;
import std.algorithm;
struct Point {
int x;
int y;
this(int x0, int y0) {
x = x0;
y = y0;
}
}
struct Rect {
int left;
int top;
int right;
int bottom;
@property int middlex() { return (left + right) / 2; }
@property int middley() { return (top + bottom) / 2; }
void offset(int dx, int dy) {
left += dx;
right += dx;
top += dy;
bottom += dy;
}
/// for all fields, sets this.field to rc.field if rc.field > this.field
void setMax(Rect rc) {
if (left < rc.left)
left = rc.left;
if (right < rc.right)
right = rc.right;
if (top < rc.top)
top = rc.top;
if (bottom < rc.bottom)
bottom = rc.bottom;
}
@property int width() { return right - left; }
@property int height() { return bottom - top; }
this(int x0, int y0, int x1, int y1) {
left = x0;
top = y0;
right = x1;
bottom = y1;
}
@property bool empty() {
return right <= left || bottom <= top;
}
void moveBy(int deltax, int deltay) {
left += deltax;
right += deltax;
top += deltay;
bottom += deltay;
}
/// moves this rect to fit rc bounds, retaining the same size
void moveToFit(ref Rect rc) {
if (right > rc.right)
moveBy(rc.right - right, 0);
if (bottom > rc.bottom)
moveBy(0, rc.bottom - bottom);
if (left < rc.left)
moveBy(rc.left - left, 0);
if (top < rc.top)
moveBy(0, rc.top - top);
}
/// updates this rect to intersection with rc, returns true if result is non empty
bool intersect(Rect rc) {
if (left < rc.left)
left = rc.left;
if (top < rc.top)
top = rc.top;
if (right > rc.right)
right = rc.right;
if (bottom > rc.bottom)
bottom = rc.bottom;
return right > left && bottom > top;
}
/// returns true if this rect has nonempty intersection with rc
bool intersects(Rect rc) {
if (rc.left >= right || rc.top >= bottom || rc.right <= left || rc.bottom <= top)
return false;
return true;
}
/// returns true if point is inside of this rectangle
bool isPointInside(Point pt) {
return pt.x >= left && pt.x < right && pt.y >= top && pt.y < bottom;
}
/// returns true if point is inside of this rectangle
bool isPointInside(int x, int y) {
return x >= left && x < right && y >= top && y < bottom;
}
}
/// character glyph
align(1)
module dlangui.core.types;
import std.algorithm;
struct Point {
int x;
int y;
this(int x0, int y0) {
x = x0;
y = y0;
}
}
struct Rect {
int left;
int top;
int right;
int bottom;
@property int middlex() { return (left + right) / 2; }
@property int middley() { return (top + bottom) / 2; }
void offset(int dx, int dy) {
left += dx;
right += dx;
top += dy;
bottom += dy;
}
/// for all fields, sets this.field to rc.field if rc.field > this.field
void setMax(Rect rc) {
if (left < rc.left)
left = rc.left;
if (right < rc.right)
right = rc.right;
if (top < rc.top)
top = rc.top;
if (bottom < rc.bottom)
bottom = rc.bottom;
}
@property int width() { return right - left; }
@property int height() { return bottom - top; }
this(int x0, int y0, int x1, int y1) {
left = x0;
top = y0;
right = x1;
bottom = y1;
}
@property bool empty() {
return right <= left || bottom <= top;
}
void moveBy(int deltax, int deltay) {
left += deltax;
right += deltax;
top += deltay;
bottom += deltay;
}
/// moves this rect to fit rc bounds, retaining the same size
void moveToFit(ref Rect rc) {
if (right > rc.right)
moveBy(rc.right - right, 0);
if (bottom > rc.bottom)
moveBy(0, rc.bottom - bottom);
if (left < rc.left)
moveBy(rc.left - left, 0);
if (top < rc.top)
moveBy(0, rc.top - top);
}
/// updates this rect to intersection with rc, returns true if result is non empty
bool intersect(Rect rc) {
if (left < rc.left)
left = rc.left;
if (top < rc.top)
top = rc.top;
if (right > rc.right)
right = rc.right;
if (bottom > rc.bottom)
bottom = rc.bottom;
return right > left && bottom > top;
}
/// returns true if this rect has nonempty intersection with rc
bool intersects(Rect rc) {
if (rc.left >= right || rc.top >= bottom || rc.right <= left || rc.bottom <= top)
return false;
return true;
}
/// returns true if point is inside of this rectangle
bool isPointInside(Point pt) {
return pt.x >= left && pt.x < right && pt.y >= top && pt.y < bottom;
}
/// returns true if point is inside of this rectangle
bool isPointInside(int x, int y) {
return x >= left && x < right && y >= top && y < bottom;
}
}
/// character glyph
align(1)
struct Glyph
{
version (USE_OPENGL) {
@ -117,84 +117,84 @@ struct Glyph
///< 12: glyph data, arbitrary size
ubyte[] glyph;
}
class RefCountedObject {
protected int _refCount;
@property int refCount() const { return _refCount; }
void addRef() {
_refCount++;
}
void releaseRef() {
if (--_refCount == 0)
destroy(this);
}
~this() {}
}
struct Ref(T) { // if (T is RefCountedObject)
private T _data;
alias get this;
@property bool isNull() const { return _data is null; }
@property int refCount() const { return _data !is null ? _data.refCount : 0; }
this(T data) {
_data = data;
if (_data !is null)
_data.addRef();
}
this(this) {
if (_data !is null)
_data.addRef();
}
ref Ref opAssign(ref Ref data) {
if (data._data == _data)
return this;
if (_data !is null)
_data.releaseRef();
_data = data._data;
if (_data !is null)
_data.addRef();
return this;
}
ref Ref opAssign(Ref data) {
if (data._data == _data)
return this;
if (_data !is null)
_data.releaseRef();
_data = data._data;
if (_data !is null)
_data.addRef();
return this;
}
ref Ref opAssign(T data) {
if (data == _data)
return this;
if (_data !is null)
_data.releaseRef();
_data = data;
if (_data !is null)
_data.addRef();
return this;
}
void clear() {
if (_data !is null) {
_data.releaseRef();
_data = null;
}
}
@property T get() {
return _data;
}
@property const(T) get() const {
return _data;
}
~this() {
if (_data !is null)
_data.releaseRef();
}
}
// some utility functions
class RefCountedObject {
protected int _refCount;
@property int refCount() const { return _refCount; }
void addRef() {
_refCount++;
}
void releaseRef() {
if (--_refCount == 0)
destroy(this);
}
~this() {}
}
struct Ref(T) { // if (T is RefCountedObject)
private T _data;
alias get this;
@property bool isNull() const { return _data is null; }
@property int refCount() const { return _data !is null ? _data.refCount : 0; }
this(T data) {
_data = data;
if (_data !is null)
_data.addRef();
}
this(this) {
if (_data !is null)
_data.addRef();
}
ref Ref opAssign(ref Ref data) {
if (data._data == _data)
return this;
if (_data !is null)
_data.releaseRef();
_data = data._data;
if (_data !is null)
_data.addRef();
return this;
}
ref Ref opAssign(Ref data) {
if (data._data == _data)
return this;
if (_data !is null)
_data.releaseRef();
_data = data._data;
if (_data !is null)
_data.addRef();
return this;
}
ref Ref opAssign(T data) {
if (data == _data)
return this;
if (_data !is null)
_data.releaseRef();
_data = data;
if (_data !is null)
_data.addRef();
return this;
}
void clear() {
if (_data !is null) {
_data.releaseRef();
_data = null;
}
}
@property T get() {
return _data;
}
@property const(T) get() const {
return _data;
}
~this() {
if (_data !is null)
_data.releaseRef();
}
}
// some utility functions
string fromStringz(const(char[]) s) {
if (s is null)
return null;

View File

@ -220,7 +220,7 @@ class Window {
private bool checkRemoveTracking(MouseEvent event) {
import std.algorithm;
bool res = false;
for(int i = _mouseTrackingWidgets.length - 1; i >=0; i--) {
for(int i = cast(int)_mouseTrackingWidgets.length - 1; i >=0; i--) {
Widget w = _mouseTrackingWidgets[i];
if (!isChild(w)) {
// std.algorithm.remove does not work for me

View File

@ -1,204 +1,209 @@
module dlangui.widgets.menu;
import dlangui.core.events;
import dlangui.widgets.controls;
import dlangui.widgets.layouts;
import dlangui.widgets.lists;
import dlangui.widgets.popup;
/// menu item properties
class MenuItem {
protected bool _checkable;
protected bool _checked;
protected bool _enabled;
protected Action _action;
protected MenuItem[] _subitems;
/// item action id, 0 if no action
@property int id() { return _action is null ? 0 : _action.id; }
/// returns count of submenu items
@property int subitemCount() {
return cast(int)_subitems.length;
}
/// returns submenu item by index
MenuItem subitem(int index) {
return _subitems[index];
}
/// adds submenu item
MenuItem add(MenuItem subitem) {
_subitems ~= subitem;
return this;
}
/// adds submenu item from action
MenuItem add(Action subitemAction) {
_subitems ~= new MenuItem(subitemAction);
return this;
}
/// returns true if item is submenu (contains subitems)
@property bool isSubmenu() {
return _subitems.length > 0;
}
/// returns item label
@property UIString label() {
return _action.labelValue;
}
/// returns item action
@property const(Action) action() const { return _action; }
/// sets item action
@property MenuItem action(Action a) { _action = a; return this; }
this() {
_enabled = true;
}
this(Action action) {
_action = action;
_enabled = true;
}
~this() {
// TODO
}
}
/// widget to draw menu item
class MenuItemWidget : HorizontalLayout {
protected MenuItem _item;
protected TextWidget _label;
@property MenuItem item() { return _item; }
this(MenuItem item) {
id="menuitem";
_item = item;
styleId = "MENU_ITEM";
_label = new TextWidget("MENU_LABEL");
_label.text = _item.label;
addChild(_label);
trackHover = true;
}
}
/// base class for menus
class MenuWidgetBase : ListWidget {
protected MenuWidgetBase _parentMenu;
protected MenuItem _item;
protected PopupMenu _openedMenu;
protected PopupWidget _openedPopup;
protected bool delegate(MenuItem item) _onMenuItemClickListener;
/// menu item click listener
@property bool delegate(MenuItem item) onMenuItemListener() { return _onMenuItemClickListener; }
/// menu item click listener
@property MenuWidgetBase onMenuItemListener(bool delegate(MenuItem item) listener) { _onMenuItemClickListener = listener; return this; }
this(MenuWidgetBase parentMenu, MenuItem item, Orientation orientation) {
_parentMenu = parentMenu;
_item = item;
this.orientation = orientation;
id = "popup_menu";
styleId = "POPUP_MENU";
WidgetListAdapter adapter = new WidgetListAdapter();
for (int i=0; i < _item.subitemCount; i++) {
MenuItem subitem = _item.subitem(i);
MenuItemWidget widget = new MenuItemWidget(subitem);
if (orientation == Orientation.Horizontal)
widget.styleId = "MAIN_MENU_ITEM";
adapter.widgets.add(widget);
}
ownAdapter = adapter;
}
protected void onPopupClosed(PopupWidget p) {
_openedPopup = null;
_openedMenu = null;
selectItem(-1);
}
protected void openSubmenu(MenuItemWidget itemWidget) {
if (_openedPopup !is null) {
_openedPopup.close();
}
PopupMenu popupMenu = new PopupMenu(itemWidget.item, this);
PopupWidget popup = window.showPopup(popupMenu, itemWidget, orientation == Orientation.Horizontal ? PopupAlign.Below : PopupAlign.Right);
popup.onPopupCloseListener = &onPopupClosed;
popup.flags = PopupFlags.CloseOnClickOutside;
_openedPopup = popup;
_openedMenu = popupMenu;
}
module dlangui.widgets.menu;
import dlangui.core.events;
import dlangui.widgets.controls;
import dlangui.widgets.layouts;
import dlangui.widgets.lists;
import dlangui.widgets.popup;
/// menu item properties
class MenuItem {
protected bool _checkable;
protected bool _checked;
protected bool _enabled;
protected Action _action;
protected MenuItem[] _subitems;
/// item action id, 0 if no action
@property int id() { return _action is null ? 0 : _action.id; }
/// returns count of submenu items
@property int subitemCount() {
return cast(int)_subitems.length;
}
/// returns submenu item by index
MenuItem subitem(int index) {
return _subitems[index];
}
/// adds submenu item
MenuItem add(MenuItem subitem) {
_subitems ~= subitem;
return this;
}
/// adds submenu item from action
MenuItem add(Action subitemAction) {
_subitems ~= new MenuItem(subitemAction);
return this;
}
/// returns true if item is submenu (contains subitems)
@property bool isSubmenu() {
return _subitems.length > 0;
}
/// returns item label
@property UIString label() {
return _action.labelValue;
}
/// returns item action
@property const(Action) action() const { return _action; }
/// sets item action
@property MenuItem action(Action a) { _action = a; return this; }
this() {
_enabled = true;
}
this(Action action) {
_action = action;
_enabled = true;
}
~this() {
// TODO
}
}
/// widget to draw menu item
class MenuItemWidget : HorizontalLayout {
protected MenuItem _item;
protected TextWidget _label;
@property MenuItem item() { return _item; }
this(MenuItem item) {
id="menuitem";
_item = item;
styleId = "MENU_ITEM";
_label = new TextWidget("MENU_LABEL");
_label.text = _item.label;
addChild(_label);
trackHover = true;
}
}
/// base class for menus
class MenuWidgetBase : ListWidget {
protected MenuWidgetBase _parentMenu;
protected MenuItem _item;
protected PopupMenu _openedMenu;
protected PopupWidget _openedPopup;
protected bool delegate(MenuItem item) _onMenuItemClickListener;
/// menu item click listener
@property bool delegate(MenuItem item) onMenuItemListener() { return _onMenuItemClickListener; }
/// menu item click listener
@property MenuWidgetBase onMenuItemListener(bool delegate(MenuItem item) listener) { _onMenuItemClickListener = listener; return this; }
this(MenuWidgetBase parentMenu, MenuItem item, Orientation orientation) {
_parentMenu = parentMenu;
_item = item;
this.orientation = orientation;
id = "popup_menu";
styleId = "POPUP_MENU";
WidgetListAdapter adapter = new WidgetListAdapter();
for (int i=0; i < _item.subitemCount; i++) {
MenuItem subitem = _item.subitem(i);
MenuItemWidget widget = new MenuItemWidget(subitem);
if (orientation == Orientation.Horizontal)
widget.styleId = "MAIN_MENU_ITEM";
adapter.widgets.add(widget);
}
ownAdapter = adapter;
}
protected void onPopupClosed(PopupWidget p) {
_openedPopup = null;
_openedMenu = null;
selectItem(-1);
}
protected void openSubmenu(MenuItemWidget itemWidget) {
if (_openedPopup !is null) {
_openedPopup.close();
}
PopupMenu popupMenu = new PopupMenu(itemWidget.item, this);
PopupWidget popup = window.showPopup(popupMenu, itemWidget, orientation == Orientation.Horizontal ? PopupAlign.Below : PopupAlign.Right);
popup.onPopupCloseListener = &onPopupClosed;
popup.flags = PopupFlags.CloseOnClickOutside;
_openedPopup = popup;
_openedMenu = popupMenu;
}
/// override to handle change of selection
override protected void selectionChanged(int index, int previouslySelectedItem = -1) {
MenuItemWidget itemWidget = index >= 0 ? cast(MenuItemWidget)_adapter.itemWidget(index) : null;
MenuItemWidget prevWidget = previouslySelectedItem >= 0 ? cast(MenuItemWidget)_adapter.itemWidget(previouslySelectedItem) : null;
if (prevWidget !is null) {
if (_openedPopup !is null)
_openedPopup.close();
}
if (itemWidget !is null) {
if (itemWidget.item.isSubmenu()) {
if (_selectOnHover) {
openSubmenu(itemWidget);
}
} else {
// normal item
}
}
if (itemWidget.item.isSubmenu()) {
if (_selectOnHover) {
openSubmenu(itemWidget);
}
} else {
// normal item
}
}
}
protected void onMenuItem(MenuItem item) {
if (_openedPopup !is null) {
_openedPopup.close();
_openedPopup = null;
}
if (_parentMenu !is null)
_parentMenu.onMenuItem(item);
else {
// top level handling
Log.d("onMenuItem ", item.id);
selectItem(-1);
selectOnHover = false;
bool delegate(MenuItem item) listener = _onMenuItemClickListener;
PopupWidget popup = cast(PopupWidget)parent;
if (popup)
popup.close();
// this pointer now can be invalid - if popup removed
if (listener !is null)
listener(item);
}
}
protected void onMenuItem(MenuItem item) {
if (_openedPopup !is null) {
_openedPopup.close();
_openedPopup = null;
}
if (_parentMenu !is null)
_parentMenu.onMenuItem(item);
else {
// top level handling
Log.d("onMenuItem ", item.id);
selectItem(-1);
selectOnHover = false;
bool delegate(MenuItem item) listener = _onMenuItemClickListener;
PopupWidget popup = cast(PopupWidget)parent;
if (popup)
popup.close();
// this pointer now can be invalid - if popup removed
if (listener !is null)
listener(item);
}
}
/// override to handle mouse up on item
override protected void itemClicked(int index) {
MenuItemWidget itemWidget = index >= 0 ? cast(MenuItemWidget)_adapter.itemWidget(index) : null;
if (itemWidget !is null) {
Log.d("Menu Item clicked ", itemWidget.item.action.id);
if (itemWidget.item.isSubmenu()) {
// submenu clicked
if (_clickOnButtonDown && _openedPopup !is null && _openedMenu._item is itemWidget.item) {
// second click on main menu opened item
_openedPopup.close();
_openedPopup = null;
selectItem(-1);
selectOnHover = false;
} else {
openSubmenu(itemWidget);
selectOnHover = true;
}
if (itemWidget.item.isSubmenu()) {
// submenu clicked
if (_clickOnButtonDown && _openedPopup !is null && _openedMenu._item is itemWidget.item) {
// second click on main menu opened item
_openedPopup.close();
_openedPopup = null;
selectItem(-1);
selectOnHover = false;
} else {
openSubmenu(itemWidget);
selectOnHover = true;
}
} else {
// normal item
onMenuItem(itemWidget.item);
}
}
}
}
/// main menu (horizontal)
class MainMenu : MenuWidgetBase {
this(MenuItem item) {
super(null, item, Orientation.Horizontal);
id = "MAIN_MENU";
styleId = "MAIN_MENU";
_clickOnButtonDown = true;
}
}
/// popup menu widget (vertical layout of items)
class PopupMenu : MenuWidgetBase {
this(MenuItem item, MenuWidgetBase parentMenu = null) {
super(parentMenu, item, Orientation.Vertical);
id = "POPUP_MENU";
styleId = "POPUP_MENU";
selectOnHover = true;
}
}
}
/// main menu (horizontal)
class MainMenu : MenuWidgetBase {
this(MenuItem item) {
super(null, item, Orientation.Horizontal);
id = "MAIN_MENU";
styleId = "MAIN_MENU";
_clickOnButtonDown = true;
}
}
/// popup menu widget (vertical layout of items)
class PopupMenu : MenuWidgetBase {
this(MenuItem item, MenuWidgetBase parentMenu = null) {
super(parentMenu, item, Orientation.Vertical);
id = "POPUP_MENU";
styleId = "POPUP_MENU";
selectOnHover = true;
}
}