-# C# Rapid Open Widgets
-[](https://www.paypal.me/GrandTetraSoftware) [](https://www.nuget.org/packages/Crow.OpenTK) [](https://travis-ci.org/jpbruyere/Crow) [](https://ci.appveyor.com/project/jpbruyere/Crow)
-
-**CROW** is a pure **C#** widget toolkit originally developed for fast GUI implementation in [OpenTK](http://opentk.github.io/) applications.
-
-You can visit the [Wiki](https://github.com/jpbruyere/Crow/wiki) or the [Project Site](https://jpbruyere.github.io/Crow/) for documentation and tutorials. _(in progress)_
+<h1 align="center">
+ <br>
+ <a href="http://www.amitmerchant.com/electron-markdownify">
+ <img src="https://github.com/jpbruyere/Crow/blob/master/Images/Icons/crow.png" alt="C.R.O.W." width="140">
+ </a>
+ <br>
+ <br>
+ C# Rapid Open Widgets
+ <br>
+<p align="center">
+ <a href="https://www.paypal.me/GrandTetraSoftware">
+ <img src="https://img.shields.io/badge/Donate-PayPal-green.svg">
+ </a>
+ <a href="https://www.nuget.org/packages/Crow.OpenTK">
+ <img src="https://buildstats.info/nuget/Crow.OpenTK">
+ </a>
+ <a href="https://travis-ci.org/jpbruyere/Crow">
+ <img src="https://travis-ci.org/jpbruyere/Crow.svg?branch=master">
+ </a>
+ <a href="https://ci.appveyor.com/project/jpbruyere/Crow">
+ <img src="https://ci.appveyor.com/api/projects/status/j387lo59vnov8jbc?svg=true">
+ </a>
+</p>
+</h1>
+
+**C.R.O.W.** is a [widget toolkit](https://en.wikipedia.org/wiki/Widget_toolkit) and
+rendering engine entirely developed in **C#**, offering a nice trade-off between
+complexity of language and performances. Crow provides a declarative interface language
+with styling and templates
+called [IML](interface-markup-language) for **Interface Markup Language** similar to
+[XAML](https://en.wikipedia.org/wiki/Extensible_Application_Markup_Language) and a binding system
+for easy c# code linking.
+<p align="center">
+ <a href="https://github.com/jpbruyere/Crow/blob/master/Images/screenshot.png">
+ <img src="https://github.com/jpbruyere/Crow/blob/master/Images/screenshot.png" width="400">
+ </a>
+</p>
+
+You can visit the [Wiki](https://github.com/jpbruyere/Crow/wiki) or the [Project Site](https://jpbruyere.github.io/Crow/)
+for documentation and tutorials.
Please report bugs and issues on [GitHub](https://github.com/jpbruyere/Crow/issues)
-Features
---------
-
-- **XML** interface definition.
-- Templates and styling
-- Dynamic binding system with code injection.
-- Inlined delegates in XML
-
-Screen shots
-------------
-
-<table width="100%">
- <tr>
- <td width="30%" align="center"><img src="https://jpbruyere.github.io/Crow/images/screenshot5.png" alt="CrowIDE" width="90%"/></td>
- <td width="30%" align="center"><img src="https://jpbruyere.github.io/Crow/images/screenshot4.png" alt="Screen Shot" width="90%" /> </td>
- <td width="30%" align="center"><img src="https://jpbruyere.github.io/Crow/images/screenshot3.png" alt="Screen Shot" width="90%"/> </td>
- </tr>
-</table>
-
-Requirements
-------------
-
-- c# compiler
+## Getting Start
+### Requirements
+- [mono > 4.5](http://www.mono-project.com/)
- [Cairo Graphic Library](https://cairographics.org/) >= 1.10
-
-Building
-------------------
+- [rsvg library](https://developer.gnome.org/rsvg/) for svg rendering
+- [nuget](https://www.nuget.org/).
+### Building from source
+_[Git](https://git-scm.com) has to be installed._
```bash
-git clone https://github.com/jpbruyere/Crow.git # Download source code from github
-cd Crow # Enter the source directory
-nuget restore Crow.sln # Restore nuget packages
-xbuild /p:Configuration=Release Crow.sln # Build with Mono
+git clone https://github.com/jpbruyere/Crow.git # Download source code from github
+cd Crow # Enter the source directory
+nuget restore Crow.sln # Restore nuget packages
+xbuild /p:Configuration=Release Crow.sln # Build with Mono
```
-
-Using CROW in your OpenTK project
----------------------------------
+### Using nuget
* add [Crow.OpenTK NuGet package](https://www.nuget.org/packages/Crow.OpenTK/) to your project.
* Derive **CrowWindow** class.
* Load some widget in the **OnLoad** override with `CrowWindow.Load` .
namespace Crow
{
+ /// <summary>
+ /// provide an easy way to get 3d border for buttons
+ /// </summary>
public enum BorderStyle {
Normal,
Raised,
Sunken
};
+ /// <summary>
+ /// simple container with border
+ /// </summary>
public class Border : Container
{
#region CTOR
#endregion
#region public properties
+ /// <summary>
+ /// use to define the colors of the 3d border
+ /// </summary>
[XmlAttributeAttribute]
public virtual Fill RaisedColor {
get { return raisedColor; }
RegisterForRedraw ();
}
}
+ /// <summary>
+ /// use to define the colors of the 3d border
+ /// </summary>
[XmlAttributeAttribute]
public virtual Fill SunkenColor {
get { return sunkenColor; }
RegisterForRedraw ();
}
}
+ /// <summary>
+ /// border width in pixels
+ /// </summary>
[XmlAttributeAttribute()][DefaultValue(1)]
public virtual int BorderWidth {
get { return _borderWidth; }
RegisterForGraphicUpdate ();
}
}
+ /// <summary>
+ /// allow 3d border effects
+ /// </summary>
[XmlAttributeAttribute][DefaultValue(BorderStyle.Normal)]
public virtual BorderStyle BorderStyle {
get { return _borderStyle; }
string image;
bool isPressed;
- Container _contentContainer;
public event EventHandler Pressed;
public event EventHandler Released;
namespace Crow
{
+ /// <summary>
+ /// templated control whose content can be hidden and shown on demand
+ /// </summary>
public class Expandable : TemplatedContainer
{
#region CTOR
#region Private fields
bool _isExpanded;
string image;
- Container _contentContainer;
#endregion
#region Event Handlers
+ /// <summary>
+ /// Occurs when control is expanded.
+ /// </summary>
public event EventHandler Expand;
+ /// <summary>
+ /// Occurs when control is collapsed.
+ /// </summary>
public event EventHandler Collapse;
#endregion
public BooleanTestOnInstance GetIsExpandable;
+ /// <summary>
+ /// mouse click event handler for easy expand triggering in IML
+ /// </summary>
public void onClickForExpand (object sender, MouseButtonEventArgs e)
{
IsExpanded = !IsExpanded;
}
-
+ /// <summary>
+ /// Implement the abstract Content property of TemplatedControl
+ /// </summary>
public override GraphicObject Content {
get {
return _contentContainer == null ? null : _contentContainer.Child;
namespace Crow
{
public class GroupBox : TemplatedContainer
- {
- Container _contentContainer;
-
+ {
#region CTOR
public GroupBox () : base(){}
public GroupBox(Interface iface) : base(iface){}
#endregion
- #region Template overrides
+ #region TemplatedContainer implementation
public override GraphicObject Content {
get {
return _contentContainer == null ? null : _contentContainer.Child;
bool _isPopped, _canPop;
Alignment popDirection;
- GraphicObject _content;
+ GraphicObject _contentContainer;
Measure popWidth, popHeight;
public event EventHandler Popped;
#endregion
public override GraphicObject Content {
- get { return _content; }
+ get { return _contentContainer; }
set {
- if (_content != null) {
- _content.LogicalParent = null;
- _content.LayoutChanged -= _content_LayoutChanged;
+ if (_contentContainer != null) {
+ _contentContainer.LogicalParent = null;
+ _contentContainer.LayoutChanged -= _content_LayoutChanged;
}
- _content = value;
+ _contentContainer = value;
- if (_content == null)
+ if (_contentContainer == null)
return;
- _content.LogicalParent = this;
- _content.HorizontalAlignment = HorizontalAlignment.Left;
- _content.VerticalAlignment = VerticalAlignment.Top;
- _content.LayoutChanged += _content_LayoutChanged;
+ _contentContainer.LogicalParent = this;
+ _contentContainer.HorizontalAlignment = HorizontalAlignment.Left;
+ _contentContainer.VerticalAlignment = VerticalAlignment.Top;
+ _contentContainer.LayoutChanged += _content_LayoutChanged;
}
}
void positionContent(LayoutingType lt){
protected override void Dispose (bool disposing)
{
- if (_content != null && disposing) {
- if (_content.Parent == null)
- _content.Dispose ();
+ if (_contentContainer != null && disposing) {
+ if (_contentContainer.Parent == null)
+ _contentContainer.Dispose ();
}
base.Dispose (disposing);
}
{
/// <summary>
/// Implement drawing and layouting for a single child, but
- /// does not implement IXmlSerialisation to allow reuse of container
+ /// does not expose child to allow reuse of container
/// behaviour for widgets that have other xml hierarchy: example
/// TemplatedControl may have 3 children (template,templateItem,content) but
/// behave exactely as a container for layouting and drawing
#endregion
#region Private fields
- string caption;
- Container _contentContainer;
- GraphicObject _tabTitle;
+ GraphicObject titleWidget;
int tabOffset;
bool isSelected;
Measure tabThickness;
base.loadTemplate (template);
_contentContainer = this.child.FindByName ("Content") as Container;
- _tabTitle = this.child.FindByName ("TabTitle");
+ titleWidget = this.child.FindByName ("TabTitle");
}
- internal GraphicObject TabTitle { get { return _tabTitle; }}
+ internal GraphicObject TabTitle { get { return titleWidget; }}
#endregion
[XmlAttributeAttribute][DefaultValue("18")]
public TemplatedContainer (Interface iface) : base(iface){}
#endregion
+ protected Container _contentContainer;
+
[XmlAttributeAttribute]public virtual GraphicObject Content{ get; set;}
#region GraphicObject overrides
namespace Crow
{
+ /// <summary>
+ /// Base class for all templated widget
+ /// </summary>
public abstract class TemplatedControl : PrivateContainer
{
#region CTOR
loadTemplate (CurrentInterface.Load (_template));
}
}
+ /// <summary>
+ /// caption property being recurrent in templated widget, it is declared here.
+ /// </summary>
[XmlAttributeAttribute()][DefaultValue("Templated Control")]
public virtual string Caption {
get { return caption; }
NotifyValueChanged ("Caption", caption);
}
}
+
#region GraphicObject overrides
+
public override void Initialize ()
{
loadTemplate ();
base.Initialize ();
}
+ /// <summary>
+ /// override search method from GraphicObject to prevent
+ /// searching inside template
+ /// </summary>
+ /// <returns>widget identified by name, or null if not found</returns>
+ /// <param name="nameToFind">widget's name to find</param>
public override GraphicObject FindByName (string nameToFind)
{
//prevent name searching in template
return nameToFind == this.Name ? this : null;
}
+ /// <summary>
+ ///onDraw is overrided to prevent default drawing of background, template top container
+ ///may have a binding to root background or a fixed one.
+ ///this allow applying root background to random template's component
+ /// </summary>
+ /// <param name="gr">Backend context</param>
protected override void onDraw (Cairo.Context gr)
{
- //onDraw is overrided to prevent default drawing of background, template top container
- //may have a binding to root background or a fixed one.
- //this allow applying root background to random template's component
gr.Save ();
if (ClipToClientRect) {
}
#endregion
+ /// <summary>
+ /// Loads the template.
+ /// </summary>
+ /// <param name="template">Optional template instance</param>
protected virtual void loadTemplate(GraphicObject template = null)
{
if (this.child != null)//template change, bindings has to be reset
Rectangle savedBounds;
bool _minimized = false;
- Container _contentContainer;
Direction currentDirection = Direction.None;
#region Events
{
#region CTOR
static Interface(){
+ CrowConfigRoot =
+ System.IO.Path.Combine(
+ Environment.GetFolderPath(Environment.SpecialFolder.UserProfile),
+ ".config");
+ CrowConfigRoot = System.IO.Path.Combine (CrowConfigRoot, "crow");
+ if (!Directory.Exists (CrowConfigRoot))
+ Directory.CreateDirectory (CrowConfigRoot);
+
loadCursors ();
loadStyling ();
findAvailableTemplates ();
#endregion
#region Static and constants
+ /// <summary>
+ /// Crow configuration root path
+ /// </summary>
+ public static string CrowConfigRoot;
/// <summary>If true, mouse focus is given when mouse is over control</summary>
public static bool FocusOnHover = false;
/// <summary> Threshold to catch borders for sizing </summary>
public static Dictionary<string, string> DefaultTemplates = new Dictionary<string, string>();
/// <summary>Finds available default templates at startup</summary>
static void findAvailableTemplates(){
+ searchTemplatesOnDisk ("./");
+ string defTemplatePath = System.IO.Path.Combine (CrowConfigRoot, "defaultTemplates");
+ searchTemplatesOnDisk (defTemplatePath);
searchTemplatesIn (Assembly.GetEntryAssembly ());
searchTemplatesIn (Assembly.GetExecutingAssembly ());
}
+ static void searchTemplatesOnDisk (string templatePath){
+ if (!Directory.Exists (templatePath))
+ return;
+ foreach (string f in Directory.GetFiles(templatePath, "*.template",SearchOption.AllDirectories)) {
+ string clsName = System.IO.Path.GetFileNameWithoutExtension(f);
+ if (DefaultTemplates.ContainsKey (clsName))
+ continue;
+ DefaultTemplates [clsName] = f;
+ }
+ }
static void searchTemplatesIn(Assembly assembly){
foreach (string resId in assembly
.GetManifestResourceNames ()