apps_mono: add text editor and Game of Life example apps for C# binding

This commit is contained in:
Vitor Sousa 2018-02-22 14:44:55 -03:00
parent f22bd3aa1f
commit 6009c1046c
8 changed files with 506 additions and 0 deletions

View File

@ -0,0 +1,10 @@
project(
'efl-example-life', 'cs',
version : '0.0.1',
meson_version : '>= 0.38.0')
efl_mono = dependency('efl-mono', version : '>=1.20.99')
efl_mono_libs = efl_mono.get_pkgconfig_variable('mono_libs')
subdir('src')

View File

@ -0,0 +1,163 @@
using System;
public class LifeBoard
{
public const int Width = 47;
public const int Height = 31;
public static int IndexForPosition(int x, int y)
{
return y * Width + x;
}
public bool[] Cells
{
get { return board; }
}
private int gen = 0;
private bool[] board, boardPrev;
private bool[] board1, board2;
private efl.loop.Timer lifeTimer = null;
private LifeRender lifeRender = null;
private void CellOn(int x, int y)
{
board1[IndexForPosition(x, y)] = true;
}
private void BoardSetup()
{
// glide
CellOn(16, 1);
CellOn(17, 2);
CellOn(18, 2);
CellOn(16, 3);
CellOn(17, 3);
// oscilate
CellOn(22, 15);
CellOn(23, 15);
CellOn(24, 15);
// block
CellOn(32, 15);
CellOn(33, 15);
CellOn(32, 16);
CellOn(33, 16);
}
public LifeBoard()
{
board1 = new bool[Height * Width];
board2 = new bool[Height * Width];
BoardSetup();
board = board1;
boardPrev = board2;
}
public void Run(efl.ui.Win win)
{
lifeTimer = new efl.loop.Timer(null, (efl.loop.Timer etimer) => {
etimer.SetInterval(0.1);
});
lifeTimer.TICK += (object sender, EventArgs ev) => {
Nextgen();
if (this.lifeRender != null)
this.lifeRender.Refresh(win);
};
}
public int SumAround(int x, int y)
{
int i, sum = 0;
int max = Width * Height;
i = IndexForPosition(x - 1, (y - 1));
if (i >= 0 && board[i])
++sum;
++i;
if (i >= 0 && board[i])
++sum;
++i;
if (i >= 0 && board[i])
++sum;
i = IndexForPosition(x - 1, y);
if (i >= 0 && board[i])
++sum;
i += 2;
if (i < max && board[i])
++sum;
i = IndexForPosition(x - 1, (y + 1));
if (i < max && board[i])
++sum;
++i;
if (i < max && board[i])
++sum;
++i;
if (i < max && board[i])
++sum;
return sum;
}
public void Nextgen()
{
int[] work = null;
++gen;
if (board == board1)
work = board2;
else
work = board1;
for (int y = 0; y < LIFE_BOARD_HEIGHT; y++)
for (int x = 0; x < LIFE_BOARD_WIDTH; x++)
{
int i = IndexForPosition(x, y);
int n = SumAround(x, y);
if (board[i])
{
if (n > 3 || n < 2)
work[i] = false;
else
work[i] = true;
}
else
{
if (n == 3)
work[i] = true;
else
work[i] = false;
}
}
boardPrev = board;
board = work;
}
public void TogglePause(efl.ui.Win win)
{
if (lifeTimer)
{
lifeTimer.Dispose();
lifeTimer = null;
}
else
{
Run(win);
}
}
public void SetRender(LifeRender render)
{
lifeRender = render;
}
}

View File

@ -0,0 +1,83 @@
using System;
public class LifeWindow
{
private LifeBoard lifeBoard;
private LifeRender lifeRender;
void ResizeEvt(efl.ui.Win win, EventArgs ev)
{
lifeRender.Layout(win);
}
void QuitEvt(efl.ui.Win win, EventArgs ev)
{
// quit the mainloop
efl.ui.Config.Exit();
}
void TouchEvt(efl.ui.Win win, efl.input.Pointer ev)
{
int cellx, celly;
var position = ev.GetPosition();
lifeRender.CellForCoords(win, position, out cellx, out celly);
int i = LifeRender.IndexForPosition(cellx, celly);
lifeBoard.Cells[i] = !lifeBoard.Cells[i];
lifeRender.RenderCell(win, cellx, celly);
}
void KeyDownEvt(efl.ui.Win win, efl.input.Key ev)
{
if (ev.GetKey() == "space")
lifeBoard.TogglePause(win);
}
public void Run()
{
lifeBoard.Run(win);
}
public LifeWindow()
{
efl.ui.Win win = new efl.Ui.WinConcrete(null, (efl.ui.Win ewin) => {
ewin.SetWinType(efl.ui.win.Type.Basic);
ewin.SetText("EFL Life");
ewin.SetAutohide(true);
});
// when the user clicks "close" on a window there is a request to hide
win.HIDE += QuitEvt;
eina.Size2D sz;
sz.W = 10 * LifeBoard.Width * win.GetScale();
sz.H = 10 * LifeBoard.Height * win.GetScale();
lifeBoard = new LifeBoard();
lifeRender = new LifeRender(win, lifeBoard);
lifeRender.Refresh(win);
win.RESIZE += ResizeEvt;
win.POINTER_DOWN += TouchEvt;
win.KEY_DOWN += KeyDownEvt;
win.SetSize(sz);
}
}
public class Example
{
public static void Main()
{
efl.All.Init(efl.Components.Ui);
var lifeWin = new LifeWin();
lifeWin.Run();
// start the mainloop
efl.ui.Config.Run();
efl.All.Shutdown();
}
}

View File

@ -0,0 +1,71 @@
using System;
public class LifeRender
{
private efl.canvas.Rectangle[] lifeCells;
private LifeBoard lifeBoard;
public LifeRender(efl.ui.Win win, LifeBoard board)
{
lifeBoard = board;
lifeBoard.SetRender(this);
lifeCells = new efl.canvas.Rectangle[LifeBoard.Height * LifeBoard.Width];
for (int y = 0; y < LifeBoard.Height; ++y)
for (int x = 0; x < LifeBoard.Width; ++x)
lifeCells[LifeBoard.IndexForPosition(x, y)] = new efl.canvas.RectangleConcrete(win);
RenderLayout(win);
}
public void CellForCoords(efl.ui.Win win, eina.Position2D coord, out int x, out int y)
{
eina.Size2D size = win.GetSize();
x = coord.X / ((double) size.W / LifeBoard.Width);
y = coord.Y / ((double) size.H / LifeBoard.Height);
}
public void RenderLayout(efl.ui.Win win)
{
eina.Size2D size = win.GetSize();
double cw = (double) size.W / LifeBoard.Width;
double ch = (double) size.H / LifeBoard.Height;
for (int y = 0; y < LifeBoard.Height; ++y)
for (int x = 0; x < LifeBoard.Width; ++x)
{
var rect = lifeCells[LifeBoard.IndexForPosition(x, y)];
// the little +1 here will avoid tearing as we layout non-multiple sizes
eina.Size2D sz;
sz.W = cw + 1;
sz.H = ch + 1;
rect.SetSize(sz);
eina.Position2D pos;
pos.X = x * cw;
pos.Y = y * ch;
rect.SetPosition(pos);
}
}
public void RenderCell(efl.ui.Win win, int x, int y)
{
int i = LifeBoard.IndexForPosition(x, y);
var rect = lifeCells[i];
if (lifeBoard.Cells[i])
rect.SetColor(0, 0, 0, 255);
else
rect.SetColor(255, 255, 255, 255);
}
public void Refresh(efl.ui.Win win)
{
for (int y = 0; y < LifeBoard.Height; ++y)
for (int x = 0; x < LifeBoard.Width; ++x)
RenderCell(win, x, y);
}
}

View File

@ -0,0 +1,14 @@
src = files([
'life_render.cs',
'life_board.cs',
'life_main.cs',
])
deps = [efl_mono]
executable('efl_example_life', src,
dependencies : deps,
cs_args : efl_mono_libs,
install : true
)

View File

@ -0,0 +1,10 @@
project(
'efl-example-texteditor', 'cs',
version : '0.0.1',
meson_version : '>= 0.38.0')
efl_mono = dependency('efl-mono', version : '>=1.20.99')
efl_mono_libs = efl_mono.get_pkgconfig_variable('mono_libs')
subdir('src')

View File

@ -0,0 +1,12 @@
src = files([
'texteditor_main.cs',
])
deps = [efl_mono]
executable('efl_example_texteditor', src,
dependencies : deps,
cs_args : efl_mono_libs,
install : true
)

View File

@ -0,0 +1,143 @@
using System;
public class TextEditor : IDisposable
{
private efl.ui.Win win;
private efl.ui.Text editor;
private efl.ui.Button toolbarNew;
private bool edited = false;
private void GUINewClickedCb(object sender, EventArgs ea)
{
editor.SetText("");
edited = true;
GUIToolbarRefresh();
}
private void GUIQuitCb(object sender, EventArgs ea)
{
efl.ui.Config.Exit();
}
private void EditorChangedCb(object sender, EventArgs ea)
{
edited = true;
GUIToolbarRefresh();
}
private efl.ui.Button GUIToolbarButtonAdd(efl.ui.Box toolbar, string name, string iconName, EventHandler func)
{
efl.ui.Button button = new efl.ui.ButtonConcrete(toolbar);
button.SetText(name);
button.CLICKED += func;
toolbar.Pack(button);
efl.ui.Image img = new efl.ui.ImageConcrete(toolbar);
img.SetIcon(iconName);
efl.ContentConcrete.static_cast(button.Part("elm.swallow.content")).SetContent(img);
return button;
}
private void GUIToolbarSetup(efl.ui.Box parent)
{
efl.ui.Box bar = new efl.ui.BoxConcrete(parent);
bar.SetHintWeight(1, 0);
bar.SetDirection(efl.ui.Dir.Horizontal);
parent.Pack(bar);
toolbarNew = GUIToolbarButtonAdd(bar, "New", "document-new", GUINewClickedCb);
// spacer box
efl.ui.Box box = new efl.ui.BoxConcrete(parent);
box.SetHintWeight(10, 0);
bar.Pack(box);
GUIToolbarButtonAdd(bar, "Quit", "application-exit", GUIQuitCb);
GUIToolbarRefresh();
}
private void GUIToolbarRefresh()
{
toolbarNew.SetDisabled(!edited);
}
public TextEditor()
{
win = new efl.ui.WinConcrete(null, (efl.ui.Win ewin) => {
ewin.SetWinType(efl.ui.win.Type.Basic);
ewin.SetText("Text Editor");
ewin.SetAutohide(true);
});
// when the user clicks "close" on a window there is a request to hide
win.HIDE += GUIQuitCb;
efl.ui.Box box = new efl.ui.BoxConcrete(win);
eina.Size2D sz;
sz.W = 360;
sz.H = 240;
box.SetHintMin(sz);
win.SetContent(box);
GUIToolbarSetup(box);
editor = new efl.ui.TextConcrete(box);
editor.SetFont("Mono", 14);
editor.SetMultiline(true);
editor.SetEditable(true);
editor.SetScrollable(true);
editor.SetScrollable(true);
editor.CHANGED += EditorChangedCb;
editor.CHANGED_USER += EditorChangedCb;
box.Pack(editor);
}
~TextEditor()
{
Dispose(false);
}
protected void Dispose(bool disposing)
{
editor.Dispose();
toolbarNew.Dispose();
win.Dispose();
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
public void Run()
{
// start main loop
efl.ui.Config.Run();
}
}
public class Example
{
public static void Main()
{
efl.All.Init(efl.Components.Ui);
var textEditor = new TextEditor();
textEditor.Run();
// dispose after quit
textEditor.Dispose();
efl.All.Shutdown();
}
}