שירות התרגום השוביניסטי של גוגל
פוסט מעניין, שיש בו כדי לשפוך אור על דרך הפעולה של שירות התרגום של גוגל. גוגל משתמשים במידע סטטיסטי כדי להציע תרגומים והטיות רלוונטיים בהתאם להקשר המילה:
NAppUpdate – Application auto-update framework for .NET
Any desktop applications programmer finds himself every now and then looking for a library providing an application auto-update functionality, that is flexible and easy-to-integrate. I had the intention of working on such a library for some time now, so it will do things the way I want it to. Last week I got to actually doing it, and I'm quite satisfied with the results.
NAppUpdate can be integrated easily with any .NET application - WinForms or WPF, and it offers great flexibility through interfaces, for feed readers, file sources, and update tasks. It also supports conditional updates, the implementation of which offers unlimited extendibility.
I based my work on Lee Treveil's .NET-Auto-Update, and although I practically rewrote almost everything, he certainly deserves this credit.
The library, released under the Apache 2.0 software license, can be downloaded / cloned from http://github.com/synhershko/NAppUpdate. Please share your thoughts, or any extension you make to it.
Update 30/03/2011: A user/developer discussion group is now available at: http://groups.google.com/group/nappupdate
Update 30/09/2010: although most of the post below is still true, it is already (!) a bit outdated. Please check the NAppUpdate tag in this blog for the latest information on the library.
At the time of this writing, here is what NAppUpdate offers:
Better splitter behavior for HTMLayout
The implementation of the splitter behavior which comes with HTMLayout, and its .NET wrapper in Nabu, suffers from several issues: it doesn't take into account RTL layouts, and the actual resizing is done while dragging the splitter itself - which is quite costly. As a result of the latter, 2 on_size notifications were pushed for every sizing operation instead of one.
I perfected it so it uses a "ghost" element to mark the splitter's position while dragging, and the actual layout changes occur only once its released from capture. Also, it now works correctly in RTL layouts, and many graphical glitches are prevented.
The code below is meant to be used with the .NET Nabu wrapper; porting it to be native HTMLayout C++ behavior is quite easy. Some more generalization work may be required before you can implement it in your solution.
using System;
using System.Collections.Generic;
using System.Text;
using Nabu.Forms.Html;
namespace MyApp.UI
{
[HtmlBehaviorName("splitter")]
public sealed class HtmlSplitterBehavior : HtmlBehaviorBase
{
#region HtmlSplitterBehavior
#region Fields
private bool _isCaptured;
private bool _isHorizontal;
private bool _isRTL;
private HtmlTag _parent;
private HtmlTag _prevSibling;
private HtmlTag _nextSibling;
private string _className;
private int _startPrevSize;
private int _startPosition;
#endregion
#region Methods
public HtmlSplitterBehavior()
: base(HtmlEventGroup.InitializationAndMouse)
{
}
#endregion
#endregion
#region HtmlBehaviorBase
protected override void OnMouse(HtmlTag sender, HtmlMouseEventArgs e)
{
if ((e.MouseState & HtmlEventMouseState.Left) != 0)
{
switch (e.Command)
{
case HtmlMouseEventCommand.Down:
{
using (HtmlTag splitter = e.Target)
{
HtmlTag parent = splitter.Parent;
HtmlTag leftSibling = splitter.PrevSibling;
HtmlTag rightSibling = splitter.NextSibling;
if ((parent != null) && (leftSibling != null) && (rightSibling != null))
{
this._parent = parent;
_isRTL = splitter.GetState(HtmlTagState.IsRTL);
this._prevSibling = leftSibling;
this._nextSibling = rightSibling;
this._isHorizontal = this._parent.GetStyle("flow") == "horizontal";
if (this._isHorizontal)
{
splitter.SetStyle(_isRTL ? "left" : "right",
e.PositionInDocument.X.ToString() + "px");
this._startPosition = e.PositionInDocument.X;
this._startPrevSize = this._prevSibling.GetLocation(HtmlTagArea.RootRelative).Width;
}
else
{
splitter.SetStyle("top", e.PositionInDocument.Y.ToString() + "px");
this._startPosition = e.PositionInDocument.Y;
this._startPrevSize = this._prevSibling.GetLocation(HtmlTagArea.RootRelative).Height;
}
splitter.SetStyle("height", this._parent.GetLocation(HtmlTagArea.BorderBox).Height + "px");
this._className = splitter.Attributes["class"];
splitter.Attributes["class"] = "splitter_ghost";
splitter.SetCapture();
this._isCaptured = true;
e.IsHandled = true;
}
}
}
break;
case HtmlMouseEventCommand.Up:
if (this._isCaptured)
{
using (HtmlTag splitter = e.Target)
{
splitter.Attributes["class"] = _className;
if (this._isHorizontal)
{
splitter.SetStyle("height", null);
int prevSize = this._startPrevSize;
if (_isRTL)
prevSize += (e.PositionInDocument.X - this._startPosition) * -1;
else
prevSize += (e.PositionInDocument.X - this._startPosition);
this._prevSibling.SetStyle(
"width",
prevSize + "px");
this._nextSibling.SetStyle(
"width",
"100%%");
}
else
{
int prevSize = this._startPrevSize + (e.PositionInDocument.Y - this._startPosition);
this._prevSibling.SetStyle(
"height",
prevSize + "px");
this._nextSibling.SetStyle(
"height",
"100%%");
}
}
this._parent = null;
this._prevSibling = null;
this._nextSibling = null;
HtmlTag.ReleaseCapture();
this._isCaptured = false;
e.IsHandled = true;
}
break;
case HtmlMouseEventCommand.Move:
if (this._isCaptured)
{
using (HtmlTag splitter = e.Target)
{
splitter.SetStyle(_isRTL ? "left" : "right", e.PositionInDocument.X.ToString() + "px");
}
e.IsHandled = true;
}
break;
}
}
base.OnMouse(sender, e);
}
#endregion
}
}
The splitter element is defined in my CSS as follows:
#mainsection > hr {padding:0;border:none;margin:0;width:0; height:*;hit-margin:3px; behavior:splitter;cursor:w-resize;}
#mainsection > hr.splitter_ghost { border: 1px solid #999; position:absolute;}