This paper introduces the Tools API in Delphi, C++ Builder, and Kylix (called "RAD tools" for brevity), and discusses some of the new features in the Tools API. The Tools API lets you extend and control the Integrated Development Environment (IDE) in the RAD tools. You can learn the basics of the Tools API in Hidden Paths of Delphi 3 (U.K., Deutschland), and read this article to learn about the new features of Delphi 6. Note that the concepts remain the same since Delphi 3, so what you learn in Hidden Paths of Delphi 3 is applicable to subsequent versions, but some of the details have changed, and many new interfaces have been added.
This section introduces the Tools API. If you are already familiar with it, you can skip ahead to What's New? The Tools API is a set of interfaces and related types and whatnot to let you extend and customize the interface of Borland's RAD tools. You can add items to the menu bar and tool bars, create new form and project wizards, open new design windows, interact with the design tools--especially the source editor and the form editor, and more. You don't have complete control over the IDE, and each release of the Delphi introduces new functionality under the Tools API umbrella.
The Tools API is declared in a single file, the ToolsAPI
unit or
<ToolsAPI.hpp>
. Even if you are working in Windows, try to
use the correct case--you never know when you might want to port to Kylix and
its case-sensitive file names.
The first step to using the Tools API is to create a wizard class. The Tools API defines several different wizard interfaces, and your wizard class must implement one or more of those interfaces:
|
Interface |
Description |
|---|---|
IOTAWizard |
Base wizard interface; every wizard must implement this. |
IOTAMenuWizard |
Wizard adds a menu item to the Help menu. Useful for tests and prototypes. |
IOTARepositoryWizard |
Base interface for project and form wizards. You must also implement one of the following interfaces: |
IOTAFormWizard |
Wizard to create a new unit, form, or other file. |
IOTAProjectWizard |
Wizard to create a new project. |
IOTARepositoryWizard60 |
New in Delphi 6 to support CLX |
Menu wizards require one additional method, GetMenuText
, which
is the menu item caption. The GetState
method returns the state of
the menu item. Even non-menu wizards must implement the GetState
method, even though it isn't called. Just in case a future version of the RAD
tools calls GetState
, though, you should probably write it so it
returns [wsEnabled]
, just in case.
Form and project wizards require an author's name, a one sentence comment,
and an icon handle, which the IDE displays in the New Items dialog box. Choose
View Details in the context menu to see examples of the comment and author. If
the page name is an empty string, the default page name is Wizards.
The IDE will also choose a default icon if your wizard returns 0 from
GetGlyph
.
The difference between a form and a project wizard is that the user can choose a form wizard to be the default form when creating a new form or when creating the main form of a default project. The user can choose a project wizard to be the default application. What the wizards actually do is up to you--you don't need to create a form in a form wizard, but it would be confusing if you don't.
The fourth kind of wizard is called an add-in wizard. It implements only the
IOTAWizard
interface. The means of invoking the wizard is entirely
up to you: you can add a button to the IDE's tool bars, add a menu item to the
menu bar, create modal or modeless windows, or hide in the background. In fact,
any wizard can do any of the above.
In Delphi 6, a repository wizard also need to implement
IOTARepositoryWizard60
to return the kind of designer needed in the
IDE, that is, VCL, CLX, or agnostic.
To create a wizard class in Pascal, derive a class from
TNotifierObject
and implement IOTAWizard
and any of
the other wizard interfaces you need. For example:
type TAutoSaveWizard = class(TNotifierObject, IOTAWizard) public constructor Create; destructor Destroy; override; // If you write your wizard in a DLL that does not use packages, // Delphi calls the Destroyed method when the wizard must be freed. // Use this method to free the wizard. In all other situations, the // Destroyed method is not called, and the IDE frees the wizard at // the appropriate time. procedure Destroyed; override; // IOTAWizard procedure Execute; // Called only for Menu, Form, and Project wizards function GetIDString: string; // return a unique string, e.g., 'Tempest Software.My wizard name' function GetName: string; // return a user-friendly string function GetState: TWizardState; // state of the menu item for IOTAMenuWizard; other wizards don't use // the state, which raises the question, Why doesn't this method get defined // in IOTAMenuWizard? end;
In C++, you need to write the code to handle multiple interfaces (stuff that
Pascal does automatically). The easiest way that I have found is to write a base
class (TNotifierObject
) that inherits from
IOTANotifier
(which inherits from IUnknown
). Derive
from TNotifierObject
all your wizard classes that must implement
interfaces. Use multiple inheritance to define more than one interface.
The TNotifierObject
class implements reference counting, and all
your derived classes call the inherited AddRef
and
Release
methods. TNotifierObject
implements the
methods of IOTANotifier
as do-nothing stubs. Most Tools API classes
so not need these methods, but your derived classes must implement them anyway.
You can usually implement them as do-nothing stubs--you don't need to call the
ancestor method because the ancestor methods don't do anything either.
Implement QueryInterface
for your class to check for the
interfaces that it implements, and then calls the inherited method to handle all
other interfaces. For example:
// Derive all wizard classes from TNotifierObject. class TNotifierObject : public IOTANotifier { public: __fastcall TNotifierObject() : d_refcount(0) {} virtual __fastcall ~TNotifierObject(); // IUnknown virtual HRESULT STDMETHODCALLTYPE QueryInterface( REFIID riid, void __RPC_FAR *__RPC_FAR *ppvObject); virtual ULONG STDMETHODCALLTYPE AddRef(void); virtual ULONG STDMETHODCALLTYPE Release(void); // IOTANotifier virtual void __fastcall AfterSave(); virtual void __fastcall BeforeSave(); virtual void __fastcall Destroyed(); virtual void __fastcall Modified(); protected: __property long RefCount={read=d_refcount}; private: long d_refcount; };
class TMenuItemWizard : public TNotifierObject, public IOTAWizard { typedef TNotifierObject inherited; public: __fastcall TMenuItemWizard(); __fastcall ~TMenuItemWizard(); void __fastcall EnableNewUnitItem(); void __fastcall AddWin32HelpItem(); void __fastcall OnClick(TObject* Sender); // IUnknown virtual HRESULT STDMETHODCALLTYPE QueryInterface( REFIID riid, void __RPC_FAR *__RPC_FAR *ppvObject); virtual ULONG STDMETHODCALLTYPE AddRef(void); virtual ULONG STDMETHODCALLTYPE Release(void); // IOTANotifier virtual void __fastcall AfterSave(); virtual void __fastcall BeforeSave(); virtual void __fastcall Destroyed(); virtual void __fastcall Modified(); // IOTAWizard virtual void __fastcall Execute(); virtual AnsiString __fastcall GetIDString(); virtual AnsiString __fastcall GetName(); virtual TWizardState __fastcall GetState(); private: TMenuItem* d_win32_help; };
As you can see in the example, a wizard inherits from
IOTANotifier
, so you must implement the methods of
IOTANotifier
. In Pascal, the TNotifierObject
class
does this for you, but in C++, you must explicitly reimplement these methods in
each derived class that uses multiple inheritance of Tools API interfaces. The
IDE does not call these methods for wizard, but it does for some of the other
classes in the Tools API.
The TNotifierObject
class is defined for you in Pascal. It is a
convenient base class for all notifier classes, wizard classes, and so on. It
defines stubs for all of the IOTANotifier
methods. In your derived
classes, you can implement only the methods that you need, and ignore the
rest.
IOTAWizard
declares several methods, some of which are
important. The ID string must be a unique string; typically you can ensure it is
unique by including your company or organization name, followed by a unique name
for the wizard (such as "Tempest Software.Auto Save Wizard". The
GetName
method returns a more user-friendly name.
See the ToolsAPI
unit for details about the wizard interfaces.
The methods are self-explanatory, except for the comments above.
The key connection between your wizard and the Tools API is a set of
interfaces called services. To access the services, start with the
variable BorlandIDEServices
, and cast it to the desired service.
All the service interfaces have names ending with Services, and every interface
whose name ends in Services is a service interface, accessible from
BorlandIDEServices
. Below is a list of the available services and a
brief description of each:
IBorlandIDEServices
BorlandIDEServices
variable is of type
IBorlandIDEServices
. The IBorlandIDEServices
interface is just a way to declare the variable as an interface so you can
easily cast it to the other services types. It doesn't provide any services of
its own.
INTAServices
INTAServices
type defines the Native Tools services, that
is, services that require direct access to the IDE's components. In
particular, your wizard has full access to the menu bar, tool bars, image
list, and action list.  Otherwise, you might upset
wizards that load after yours. If your wizard adds actions, menu items, or
buttons, though, be sure to free everything when your wizard is freed.
IOTAActionServices
IOTADebuggerServices
IOTAMessageServices
IOTAModuleServices
IOTAPackageServices
IOTAServices
IOTAWizardServices
RegisterPackageWizard
in a package or call
the registration procedure that is passed to a DLL's initialization function.
IOTAToDoServices
IOTAEditorServices
IOTAKeyboardServices
For example, to get the module interface, given a file name, you must use the
module services interface and call the FindModule
method:
var Module: IOTAModule; begin Module := (BorlandIDEServices as IOTAModuleServices).FindModule(FileName);
_di_IOTAModuleServices Services; BorlandIDEServices.QueryInterface(IID_IOTAModuleServices,(void**) &Services); _di_IOTAModule Module = Services->FindModule(FileName);
The _di_IOTAModule
type is a smart pointer. You can treat
it as an IOTAModule*
, but it keeps track of reference counting the
same way that Pascal does for interfaces. In Pascal, the compiler understands
the as
operator, but in C++ you can use QueryInterface
to cast BorlandIDEServices
to a particular Services interface. The
_di_
types are created with the
DECLARE_DINTERFACE_TYPE
macro. All the Tools API interfaces are
declared as _di_
types, so you don't need to mess with
DECLARE_DINTERFACE_TYPE
, but you should know it exists in case you
create your own interfaces.
If you don't use the DECLARE_DINTERFACE_TYPE
macro and instead
use the interface types directly, you do not get the advantage of reference
counting. If you have a method that holds an interface reference for a short
time, and you can clearly see where the interface reference is created and where
it is released, you might feel safe in skipping the reference counting. In most
cases, however, the extra safety is well-worth the extra effort. I encourage you
to use the reference counted interfaces as much as possible.
A module represents a file that is open in the IDE. Each form, source file, and project resource file has a module interface. A module can have one or more editors associated with it, such as a source editor for a unit's source code and a form editor for the visual form. A module can have multiple files, such as a .dfm file, a .cpp file, and an .hpp header file in C++.
Modules represent open files only. You can ask the Tools API for a list of the files in a project, but in that case, you get a module info interface for each file name. Using a module info, you can open a file and get a module interface.
Just because a file has a module interface does not mean the file has an
editor, though. The project source file, for example, is always open, but is not
always visible. If a file is visible in an editor, it has an editor interface:
source editor, form editor, and so on. To get the editors, call
GetModuleFileCount
to find out how many editors are associated with
a module, then call GetModuleFileEditor
to get each
IOTAEditor
interface. You can cast that interface to a particular
interface, such as IOTAFormEditor
or IOTASourceEditor
.
For example,
var I: Integer; begin for I := 0 to Module.GetModuleFileCount-1 do FileList.Add(Module.GetModuleFileEditor(I));
int count = Module->GetModuleFileCount(); for (int i = 0; i < count; ++i) FileList->Add(Module->GetModuleFileEditor(i));
Using a module interface, you can close the file, save the file, check whether the file has been modified, and register a notifier to learn when the user saves, modifies, or closes the file.
A notifier tells your wizard about interesting events. Your wizard can learn when the user opens and closes files, installs and uninstalls packages, starts a debugging session, and more. The table below lists the kinds of notifiers that exist in the Tools API, and what kinds of interfaces they monitor.
| Notifier | Monitors | Notifies your wizard when: |
|---|---|---|
IOTAIDENotifier |
Global events |
the user opens files, installs packages, compiles a project, etc. |
IOTAEditorNotifier |
IOTASourceEditor |
the user opens, closes, or activates a source editor view |
IOTAFormNotifier |
IOTAFormEditor |
the form editor is activated or saves a form, or when adding, removing, or renaming a component |
IOTAModuleNotifier |
IOTAModule |
before saving, after saving, modifying, or renaming a file |
IOTABreakpointNotifier |
IOTABreakpoint |
a breakpoint is changed, deleted, or triggered |
IOTAThreadNotifier |
IOTAThread |
evaluation completes in a thread |
IOTAProcessNotifier |
IOTAProcess |
a thread is created or destroyed, or when a module is added or removed from a process |
IOTADebuggerNotifier |
Debugger |
a debug process begins or ends, or when a breakpoint is added or removed |
IOTAEditLineNotifier |
IOTAEditLineTracker |
the user edits text |
To create a notifier, you must write a class that implements one or more
notifier interfaces. Your wizard creates an instance of your notifier and
registers the notifier with the Tools API. The AddNotifier
method
returns an integer, which your wizard must keep track of. To unregister the
notifier, pass the same integer to RemoveNotifier
.
Always unregister your notifier when you are done using it. Most notifiers
call the Destroyed
method when the interface being monitored is
about to be destroyed. For example, a module notifier's Destroyed
method is called when the user closes a file and the IDE must free the module
interface. The module notifier's Destroyed
method should unregister
the notifier. In most cases, that should be sufficient to free the notifier. If
your wizard keeps any references to the notifier, be sure to set the references
to nil
or NULL
when the notifier is destroyed. IDE
notifiers' Destroyed
method is not called. Typically, a wizard will
unregister an IDE notifier when the wizard is destroyed.
As with wizards, you must define your own notifier class, so C++ users face more work than Pascal users. You can use the old-style API notifiers, but they have less functionality. One possibility is to write your notifiers in Pascal, even if the rest of your wizard is in C++.
The following example is a module notifier. It gets notification when something happens to a file, such as closing, saving, renaming, etc. This particular notifier keeps track of the module interface, so it can unregister itself. Your module notifier class should probably do something similar because the module notifier interface does not tell you which module is the subject of the notification. It's up to you to keep track of that information. Thus, you should create a separate instance of your notifier class and register each instance with exactly one module.
type TModule = class(TNotifierObject, IOTAModuleNotifier) private fModule: IOTAModule; // Tools API module interface fNotifierIndex: Integer; protected procedure AddNotifier; procedure RemoveNotifier; property NotifierIndex: Integer read fNotifierIndex; public constructor Create(const Module: IOTAModule); destructor Destroy; override; // Delphi calls BeforeSave, AfterSave, Destroyed, and Modified // as appropriate for the files that make up this module. procedure AfterSave; override; procedure BeforeSave; override; procedure Destroyed; override; procedure Modified; override; // IOTAModuleNotifier method: called after a rename procedure ModuleRenamed(const NewName: string); property Module: IOTAModule read fModule; end;
Now you see a situation where Pascal uses the IOTANotifier
methods. When the user saves a file, the notifier is called before the file is
actually saved and after it has been saved. The Modified
method is
called every time the user makes a change, e.g., for every keystroke, so don't
do any heavy computation there. The IDE calls Destroyed
when the
file is closed. Your notifier must unregister and free itself.
Registering a notifier works the same way throughout the new API. Call
AddNotifier
and pass the interface as an argument.
AddNotifier
returns an integer index. Save that index and pass it
to RemoveNotifier
to unregister the notifier. You can unregister
notifiers in any order, but you must remember to unregister every notifier.
Read the ToolsAPI.pas or Toolapi.hpp file, and you
will notice that many interfaces have AddNotifier
methods. Look at
the argument type to learn what kind of notifier it takes. That tells you which
interface you must implement for that kind of notifier.
After you write the wizard, you need to inform the IDE about your new wizard. You have two choices: you can put the wizard into a design-time package and install the package in the IDE, or you can put the wizard in a DLL (Windows) or shared object (Linux). I'll use the generic term "library" for a DLL or shared object, depending on the operating system. If you use a library, you need to tell the IDE about your library. On Windows, add a registry entry under the Experts key for the RAD tool (e.g., HKEY_CURRENT_USER\Software\Borland\Delphi\6.0\Experts). The name of your entry should be the name of your wizard, and the value is the complete path to the DLL. The IDE loads all the experts and wizards when it starts and unloads them when it shuts down. Under Linux, add an entry to the user's .borland/delphi60rc file, in the [Experts] section. Again, the name is the wizard name, and the value is the complete path to the shared object. For example,
[Experts] Tempest Software.Sort=/usr/local/lib/libsort.so
The advantage of using design-time packages is that you can load and unload the package many times without starting, stopping, and restarting the program. Thus, you probably want to use a package during development.
Remember that if your wizard uses any of the interfaces whose names start
with INTA
, you must use the appropriate VCL package
(VCLx0 on Windows where x is the version number, or
bplvcl.so.x on Linux). Because wizards are design-time entities and they
are useless without the RAD tool IDE, you can never run a wizard without the VCL
and related packages. In most cases, you will want to use packages anyway.
The drawback to using packages is that all the design-time packages reside in the global name space. In C++, you can use a separate namespace for your classes, but forms all share a single name space (not the same as a C++ namespace). In Pascal, all unit names reside in the same, global name space. Using a DLL avoids any potential for name collisions.
To use a package in Pascal, implement the unit's Register
method
and call RegisterPackageWizard
, as shown below:
procedure Register; begin RegisterPackageWizard(TAutoSaveWizard.Create); end;
In C++, declare the RegisterPackageWizard
procedure in the
ToolsAPI
namespace, and your Register
procedure in
your package's namespace:
namespace ToolsAPI { DECLARE_DINTERFACE_TYPE(IOTAServices); DECLARE_DINTERFACE_TYPE(IOTAWizard); extern PACKAGE void __fastcall RegisterPackageWizard(const _di_IOTAWizard Wizard); } // Register the wizard in a package. namespace Menuitemreg { void PACKAGE __fastcall Register() { _di_IOTAWizard wizard = new TMenuItemWizard(); RegisterPackageWizard(wizard); } }
To register a wizard in a library, you must implement an initialization
function. The function has the name INITWIZARD0001
. In Pascal, you
can export a function of any name with the name WizardEntryPoint
.
In C++, use that given name or a module definition file.
The IDE calls the initialization function, passing an interface reference for
BorlandIDEServices
, a pointer to a wizard-registration function,
and a pointer where you can store a termination procedure. Usually, your
wizard's destructor is all you need for the termination, but if you want to, you
can store a pointer to a procedure that takes no parameters, and the IDE will
call it when the wizard is unloaded.
If you use the VCL package, you don't need to set
BorlandIDEServices
, but if your library does not use any of the VCL
packages, you must save the first argument in the
BorlandIDEServices
variable:
function InitWizard(Services: IBorlandIDEServices; RegisterProc: TWizardRegisterProc; var Terminate: TWizardTerminateProc): Boolean; stdcall; begin BorlandIDEServices := Services; // only needed when linking without packages // Save the application window handle. Application.Handle := (Services as IOTAServices).GetParentHandle; // Create and register the wizard(s). RegisterProc(TAutoSaveWizard.Create); // Return true for success, and false for failure. Result := True; end; exports InitWizard name WizardEntryPoint;
extern "C" __export bool __stdcall INITWIZARD0001(IBorlandIDEServices* services, TWizardRegisterProc registerProc, TWizardTerminateProc& terminate) { BorlandIDEServices = services; // only needed when linking without packages // Save the application window handle. _di_IOTAServices ota_services; services->QueryInterface(IID_IOTAServices, (void**) &ota_services); Application->Handle = ota_services->GetParentHandle(); // Create and register the wizard(s). registerProc(new TMenuItemWizard()); // Return true for success, and false for failure. return true; }
Version 4 of the Tools API first introduced COM-style interfaces instead of abstract virtual base classes. Version 5 added a number of new interfaces. Version 6 adds a few more.
All the declarations for the new API are in a single file, ToolsAPI.pas or ToolsAPI.hpp. The RAD tools don't come with any Tools API documentation, but with a little help, you can figure out most of the API from the source code, and this paper should give you the help you need.
The Tools API interfaces come in two flavors: OTA and NTA, for Open Tools API and Native Tools API. The difference is that NTA interfaces must be compiled and linked with the VCL packages. The NTA interfaces have direct access to certain objects in the IDE, so you must use packages to make sure the pointers and references remain valid.
OTA interfaces, on the other hand, have a degree of separation that lets you
write your wizard in any language and build it into a separate library. The
language you use to write the library must support Borland's calling conventions
(__fastcall
in C++, register
in Pascal). The library
must also use Borland's shared memory manager (memmgr.lib in C++,
ShareMem
in Pascal) in Windows and Borland's shared exception
manager in Linux. Strings use Pascal-style strings (AnsiString
in
C++). But all the communication between the IDE and your wizard takes place via
interfaces, not through Pascal or C++ objects.
Because the new Tools API uses interfaces, most of your memory management
headaches are gone. Usually, you need to make sure your wizard keeps track of
interface references, not object references. The proper way to free an
interfaced object is to release all the references to it, and let its reference
count become zero. If you try to call Free
explicitly, you will get
an Invalid Pointer Operation (EInvalidPointer
) exception.
New in Delphi 6 is support for CLX and VCL. Most of the changes are internal and hidden from view. (That's the point of the Tools API--to present a simple interface to the internal guts of the IDE.)
The first change is the additon of IOTARepositoryWizard60
. A
form or project wizard should implement this interface to tell Delphi whether
the wizard is creating a VCL form or project, a CLX form or project, or if it
doesn't matter. Implement the GetDesigner
method, which returns a
string. Use the constants dCLX
, dVCL
, or
dAny
.
The IOTAModuleInfo
interface has also changed. It returns a
custom module ID (a string that provide additional information when
ModuleType
is omtCustom
) and information about
additional files that make up the logical module.
For Kylix developers, I have some good news and some bad news. The good news is that the Tools API has not changed since Delphi 5. The bad news is that the Tools API has not changed since Delphi 5.
The Tools API in Kylix is almost exactly the same as it is in Delphi 5. If you have a lot of existing Tools API code, it might seem to be a blessing, but if you think about the ramifications, you might change your mind. For example, the Tools API uses the VCL, not CLX. (Astute readers of the previous section have already caught the fact that libraries need the appropriate VCL package, even on Linux.)
"Wait a minute!" you cry. "Isn't Kylix all about cross-platform development? A brand-new component hierarchy? What's the VCL doing on Linux?"
The Kylix IDE is largely a port of the Delphi 5 IDE from Windows to Linux.
Borland did not have enough time to rewrite the IDE from scratch in CLX, so they
ported the existing VCL-based IDE. It's not running under a Windows emulator,
but there is a library that provides some of the Windows API and maps the
Windows API calls to native Linux functions and system calls. The VCL sits on
top of this library. It's all part of the vcl package. (Yes, that's
vcl
not vcl60
. Linux has its own way to support
version numbers for shared objects, so the numbers come after the file
extension, so the full file name is bplvcl.so.6.0. That means you
don't need to rewrite all your package source files for every new release of
Kylix.)
Because the VCL and CLX maintain separate event queues, running in separate threads, you must not try to create a CLX form from the VCL thread or vice versa. In other words, don't use CLX in your Tools API wizard.
You can use the VCL, but the Kylix IDE lets you edit only CLX forms. If you want to use the VCL, therefore, you can design your forms in Delphi 5, then recompile the files in Kylix.
You will need to maintain separate package source files, though. The required packages are different for Kylix than for Delphi for Windows, and Borland does not support conditional compilation directives in packages. (More specifically, the IDEs don't understand conditional compilation directives, so you cannot use the package managers on Windows or Linux.)
The designide package contains the ToolsAPI
unit.
You can write a wizard that uses only CLX and the ToolsAPI
unit,
but you cannot create any visual forms. You might use baseclx, for
example. If you do any visual work, remember to use the VCL, not VisualCLX, in
which case you need the vcl package, too.
Register your wizard in the usual way: declare a procedure named
Register
(case is important!), and have the Register
procedure call RegisterPackageWizard
for each wizard instance you
want to register.
Tools API extensions are usually binary compatible between Delphi and C++ Builder with the same version number. Just load the package or library and go! "Usually" means that sometimes new bugs are introduced in the C++ Builder release, but the design and interfaces are the same. If you need to cross version numbers, you can usually get by with a simple recompilation, provided you are not using an interface that is unavailable in an older release.
Now it's time to apply the theory you've been learning by writing real wizards. Different examples are given for Delphi for Windows, C++ Builder for Windows, and Kylix Pascal.
Now it's time to apply the theory you've been learning by writing a real wizard. This example is an auto-save wizard. It sits in the background, automatically saving all the files you are editing. If the IDE were to crash unexpectedly, the next time you want to edit a file, the auto-save wizard asks if you want to restore the saved copy.
The heart of this wizard is the TIdeFile
class and its
subclasses. Each file is represented by a TIdeFile
object. When the
user opens a file, the IDE notifier creates a TIdeFile
object for
file, according to the type of the file's editor. The difference between the
subclasses is the AutoSave
method, which knows how to save a backup
copy of its particular kind of file.
type TIdeFile = class private fEditor: IOTAEditor; fFileName: string; public constructor Create(const Editor: IOTAEditor); procedure AutoSave; virtual; abstract; procedure Renamed; virtual; procedure Saved; virtual; property Editor: IOTAEditor read fEditor; property FileName: string read fFileName; end; TFormFile = class(TIdeFile) public procedure AutoSave; override; end; TSourceFile = class(TIdeFile) public procedure AutoSave; override; end;
Saving a form file is easy because the new API has a method that saves the
form's resource to a stream. The only trick is that you need an
IStream
interface, not a TStream
object. Fortunately,
that's easy with a TStreamAdapter
interface:
procedure TFormFile.AutoSave; var Stream: TStream; Adapter: IStream; begin // The form editor interface needs an IStream, so create // an adapter for the TAutoSaveStream. Stream := TAutoSaveStream.Create(Editor.FileName); try Adapter := TStreamAdapter.Create(Stream); try (Editor as IOTAFormEditor).GetFormResource(Adapter); except on Ex: Exception do { Propagate the exception, but with the file name. } raise Exception.CreateFmt(S_Error, [Editor.Filename, Ex.Message]); end; finally Stream.Free; end; end;
Saving a source file isn't too difficult. The Tools API has an edit reader interface, which lets your wizard read the editor's source buffer. The wizard reads the buffer in 8KB chunks. You can choose a different size. The only thing you can't do is read the entire buffer at once. The Tools API lacks any simple interface for determining the size of a file in the source editor.
// Auto-save a file in the text editor. procedure TSourceFile.AutoSave; const BufSize = 8192; var SourceEditor: IOTASourceEditor; Reader: IOTAEditReader; Buffer: PChar; Count: Integer; Stream: TStream; begin Buffer := nil; Stream := nil; SourceEditor := Editor as IOTASourceEditor; Reader := SourceEditor.CreateReader; try GetMem(Buffer, BufSize); Stream := TAutoSaveStream.Create(Editor.FileName); try repeat Count := Reader.GetText(Stream.Position, Buffer, BufSize); Stream.WriteBuffer(Buffer^, Count); until Count <> BufSize; except on Ex: Exception do { Propagate the exception, but with the file name. } raise Exception.CreateFmt(S_Error, [Editor.Filename, Ex.Message]); end; finally Stream.Free; FreeMem(Buffer); end; end;
The wizard defines an IDE notifier, which gets notified when the user is about to open a file and after the user has opened a file. When the user is about to open a file, the wizard checks for an autosaved file. If one is present, that means the system crashed and left the file behind, so the wizard asks the user if he or she wants to use the autosaved file, use the current file, or cancel. If the user chooses cancel, the wizard tells the IDE not to open the file. If the user chooses to use the current file, the autosaved file is deleted, and if the user wants to restore the autosaved file, the wizard overwrites the current file with the autosaved file, and lets the IDE open the file normally.
After the user opens a file, the wizard creates a module notifier for it, and keeps track of the files for the module.
function TAutoSaveWizard.FileOpening(const FileName: string): Boolean; var SaveFile: string; begin Result := False; SaveFile := MakeAutoSaveFileName(FileName); if not FileExists(SaveFile) then Exit; MessageBeep(Mb_IconQuestion); case MessageDlg(Format(S_LoadPrompt, [Filename]), mtConfirmation, mbYesNoCancel, 0) of mrYes: RestoreAutoSave(SaveFile, FileName); mrNo: DeleteFile(SaveFile); mrCancel: Result := True; end; end;
The rest of the wizard manages the bookkeeping of lists of files, the user interface, and so on. Look at the complete source code for this wizard on the conference CD-ROM.
Because module interfaces don't work correctly when writing a wizard in C++, this example shows a different wizard. Delphi and C++ Builder have a menu item on the File menu called New Unit. This menu item is a short cut to create a new unit, just like choose Unit from the New Items dialog box. This menu item is hidden by default. If you want to be able to create a unit quickly, you might prefer that the menu item be visible. This wizard looks up the menu item and makes it visible.
The wizard also adds a menu item to the Help menu. A menu wizard adds menu items to the end of the Help menu. If you want more control over where the menu item is added, you need to write an Add-in wizard and create your own menu item, which is exactly what this wizard does. The declaration for the wizard class appeared at the start of this paper.
Below is the function that adds the menu item for the Win32 API help file.
You can see how it retrieves an INTAServices
interface and uses
that to get a pointer to the IDE's main menu. You can do almost anything you
want because it is the real pointer to the real TMainMenu
object.
That means you need to be extra careful not to make mistakes, mistakes that
might delete all the menu items from the menu, for example.
// Add a menu item to the Help menu. The new menu item opens the Win32 help file. void __fastcall TMenuItemWizard::AddWin32HelpItem() { // Find the Help>Index menu item _di_INTAServices nta_services; if (Failed(BorlandIDEServices->QueryInterface(IID_INTAServices, (void**)&nta_services))) throw * new Exception("NTAServices failure"); TMainMenu* MainMenu = nta_services->GetMainMenu(); TMenuItem* HelpMenu = FindMenuItem(MainMenu->Items, "HelpMenu"); if (HelpMenu == NULL) throw * new Exception("Cannot locate Help menu"); TMenuItem* IndexItem = FindMenuItem(HelpMenu, "HelpTopicSearchItem"); if (IndexItem == NULL) throw * new Exception("Cannot locate Help>Index menu item"); // Add a menu item to the Help menu. d_win32_help = NewItem("&Win32 API", 0, false, true, OnClick, 0, "HelpWin32Item"); HelpMenu->Insert(IndexItem->MenuIndex, d_win32_help); }
To register the wizard, you can install it in its own design-time package, or use a DLL that is linked with the VCL40 package. Because this wizard uses the INTAServices interface, you must use the VCL40 package. To install the wizard as part of a package, call RegisterPackageWizard:
namespace ToolsAPI { DECLARE_DINTERFACE_TYPE(IOTAServices); DECLARE_DINTERFACE_TYPE(IOTAWizard); extern PACKAGE void __fastcall RegisterPackageWizard(const _di_IOTAWizard Wizard); } // Register the wizard in a package. namespace Menuitemreg { void PACKAGE __fastcall Register() { _di_IOTAWizard wizard = new TMenuItemWizard(); RegisterPackageWizard(wizard); } }
If you want to use a separate DLL, write the initialization function as shown
below. You can register as many wizards as you want. Return true
for success or false
for failure.
// Register the wizard in a DLL. extern "C" __export bool __stdcall INITWIZARD0001(IBorlandIDEServices* services, TWizardRegisterProc registerProc, TWizardTerminateProc& terminate) { _di_IOTAServices ota_services; services->QueryInterface(IID_IOTAServices, (void**) &ota_services); Application->Handle = ota_services->GetParentHandle(); registerProc(new TMenuItemWizard()); return true; }
This example is a port of an IDE extension I wrote in Delphi. To port it to Kylix, I had to create a new package, but I made very few other changes. For your convenience, the Delphi package is included on the CD-ROM, so you can use this code in Delphi or Kylix. The discussion below applies equally to Delphi and Kylix.
This wizard sorts text in the source editor. The user highlights a block of text in the usual manner, then invokes the wizard with a keyboard shortcut or a menu item. The wizard reads the selected text into a string list, sorts the text, and writes the sorted text back to the source editor.
The main wizard class is in the SortWiz
unit. The wizard adds a
menu item to the IDE's menu bar (Edit > Sort). It also registers a key
binding for Ctrl+K, S. The menu item brings up the sort parameters dialog box,
but the key binding sorts using the current parameters. I think this is a
convenience for the user, but you are free to change this if you disagree.
Adding a menu item is straightforward because you are using the actual
TMainMenu
component from the IDE, so you can use all the familiar
code in the Menus
unit. The keyboard shortcut is unique to the
Tools API, so take a closer look at how it works. To create a keyboard shortcut,
you need to define a class that implements IOTAKeyboardBinding
. The
binding object provides information about the keyboard binding (e.g., a
user-friendly name and a unique identifier), and it provides a callback for
handling the keystroke event:
type TSortBinding = class(TNotifierObject, IOTAKeyboardBinding) protected function GetBindingType: TBindingType; function GetDisplayName: string; function GetName: string; procedure BindKeyboard(const BindingServices: IOTAKeyBindingServices); procedure KeyProc(const Context: IOTAKeyContext; KeyCode: TShortCut; var BindingResult: TKeyBindingResult); end; // Bind Ctrl+K, S to the Edit>Sort function. procedure TSortBinding.BindKeyboard(const BindingServices: IOTAKeyBindingServices); const Ctrl_K = ScCtrl + Ord('K'); begin BindingServices.AddKeyBinding([Ctrl_K, Ord('S')], KeyProc, nil, kfImplicitShift); end; function TSortBinding.GetBindingType: TBindingType; begin Result := btPartial; end; function TSortBinding.GetDisplayName: string; begin Result := 'Sort'; end; function TSortBinding.GetName: string; begin Result := 'Tempest Software.Sort'; end; procedure TSortBinding.KeyProc(const Context: IOTAKeyContext; KeyCode: TShortCut; var BindingResult: TKeyBindingResult); begin SortSelection(Context.EditBuffer); BindingResult := krHandled; end;
When the wizard starts up, it registers the binding, and when it shuts down, it removes the binding:
// Add the menu item when creating the expert. constructor TSortWizard.Create; var MainMenu: TMainMenu; EditMenu: TMenuItem; I: Integer; begin inherited; fBindingIndex := (BorlandIDEServices as IOTAKeyboardServices).AddKeyboardBinding(TSortBinding.Create); ... end; // Free the menu item when destroying the expert. destructor TSortWizard.Destroy; begin (BorlandIDEServices as IOTAKeyboardServices).RemoveKeyboardBinding(fBindingIndex); ... inherited Destroy; end;
The SortReg
unit registers the wizard. I always like to put the
registration code in a separate unit, which lets me work with the wizard and its
code without stumbling over the registration code.
SortSel
does the main work of sorting the selection. There are
two possibilities when selecting text: columnar selection or linear
selection.
In columnar selection, the user identifies two corners of a text rectangle in the editor. Selected lines are not contiguous. What make columnar selections tricky is the possibility of having tabs in the selection or before the selection on one or more lines. After sorting, the wizard tries to ensure the text lines up nicely. It does so by keeping track of the text position of the start of each line fragment. It inserts the sorted text at the same position on each line.
In linear selection, the user picks two endpoints, and all characters in between are part of the selection. The exact endpoints might include or exclude the character after the end of the selection. The distinction isn't important because the wizard sorts entire lines of text, so the selection is extended to include the entire line.
The Tools API has three ways to identify a position in the editor:
The Tools API can convert between the different kinds of positions, which is important because different functions need different information. For example, the current selection is specified in terms of character positions. The sort wizard converts to buffer positions to read the text to sort:
// Get the limits of the selected text. BlockStart := Buffer.BlockStart; BlockAfter := Buffer.BlockAfter; // Sort entire lines, so modify the positions accordingly. BlockStart.CharIndex := 0; // start of line if BlockAfter.CharIndex > 0 then begin // Select the entire line by setting the After position // to the start of the next line. BlockAfter.CharIndex := 0; Inc(BlockAfter.Line); end; // Convert the character positions to buffer positions. StartPos := View.CharPosToPos(BlockStart); EndPos := View.CharPosToPos(BlockAfter); // Get the selected text. Reader := Buffer.CreateReader; SetLength(Text, EndPos - StartPos - 1); Reader.GetText(StartPos, PChar(Text), Length(Text));
After sorting, the editor buffer is modified by deleting the old text and inserting the newly sorted text:
Writer := Buffer.CreateUndoableWriter; Writer.CopyTo(StartPos); Writer.DeleteTo(EndPos); Writer.Insert(PChar(Text));
Finally, the sorted text is selected and scrolled into view:
// Make sure the top of the sorted text is visible. // Scroll the edit window if ncessary. if (BlockStart.Line < View.TopPos.Line) or (BlockAfter.Line >= View.TopPos.Line + View.ViewSize.CY) then begin View.ConvertPos(False, TopPos, BlockStart); View.TopPos := TopPos; end; // Select the newly inserted, sorted text. Buffer.BlockVisible := False; Buffer.BlockType := btNonInclusive; Buffer.BlockStart := BlockStart; Buffer.BlockAfter := BlockAfter; Buffer.BlockVisible := True;
The status bar message informs the user that the text has been sorted. (Sometimes, the text starts out sorted, so the message tells the user that something happened, even if the result is identical to the starting text.)
SortParms
lets the user adjust some sorting parameters. If the
user chooses the Edit>Sort menu item, the sort parameters dialog box is
shown. The user can sort in ascending or descending order, choose case
sensitivity, and decide whether to ignore Pascal keywords. The latter option
lets the user sort methods in a class declaration without putting all functions
before all procedures. The sort parameters dialog box is shown below.
To use this wizard in Kylix, simply compile and install the
sort.dpk
package. It's that simple.
The Tools API is big, much too big to cover in a single paper. This paper introduces the basics, and armed with that knowledge, you can figure out much more on your own. For some extra help, Hidden Paths of Delphi 3 explains the concepts, for example, how the Tools API manages a project's resources. You can apply these same concepts to newer versions of the API, just change the classes to use the new interfaces.
Every release adds new interfaces and new features to the Tools API. Ultimately, the source file ToolsAPI.pas is the sole source of information about the new API features. Once you get used to the style of the interfaces, you will find them fairly easy to work with.
For example, any interface whose name ends with Notifier
is a
notifier. All the notifiers work in the same manner: you must write a class that
implements the notifier interface, register your notifier object, and Delphi
calls back to your object when something interesting happens. Now that you know
how to work with IDE and module notifiers, you can figure out how to work with,
say, debugger notifiers or editor notifiers.
Similarly, all the Services interfaces are the main interfaces between your
wizard and the IDE. Delphi and C++ Builder define the services objects, and your
wizard casts the BorlandIDEServices
interface to the desired
service to call its methods.
Read the Tools API source file to learn about the other services and interfaces that are available. The Tools API is powerful and useful. Add the features that you've always felt were missing from the IDE. Customize the IDE to suit your needs. If you ever get stuck, drop a note in the Tools API newsgroup.
Ray Lischner is the author of Delphi in a Nutshell, the award-winning guide to the Delphi Pascal language. Ray recently completed his M.S. in Computer Science at Oregon State University, and is now returning to writing, slaving away at RAD Programming for Linux and other books. He also wrote Shakespeare for Dummies, Hidden Paths of Delphi 3, and Secrets of Delphi 2. Ray's articles appear in a variety of technical magazines, and he is a frequent speaker at conferences and user groups meetings across the country.


Welcome to the Hyperaudio Styleguide. The purpouse of this styleguide is to document all, even tiniest, elements of Hyperaudio’s user interface.
Styleguide requires Hyperaudio base stylesheet, hence all that works within the Styleguide will work on the site or any of the apps as well.
Modules documented in the Styleguide (especially components and combos) are build with flexibility in mind, hence they will adapt to the bounding box. For that it is important to keep the layout classes and presentational classes separated. More on that in the Grid section.
Hyperaudio UI architecture depends principally on a few Node Modules used for CSS compilation and Bower which is used to handle dependencies.
$ cd directory $ npm install $ bower install $ gulp
Whenever any style changes are required, enter project directory, follow instructions found above (Running the thing) and make necessary edits in the /src/styles
directory. CSS files will automagically be compiled and minimized.
And nobody will record you while you snore.


Military Drone Crashes at Backyard in Russian City
In a tiny town in the Ryazan Region 200 km from Moscow, an Orion military UAV crash-landed, according to Sergei Bubenev, a investigator specialising in major cases for the Moscow inter district's Investigative Committee for Transport.
The Orion unmanned aerial vehicle crashed 70 metres from residential buildings, according to the press secretary of the Governor of the Ryazan Region Denis Arapov.
According to him “there were no casualties or destruction caused by the accident” .
The vehicle was performing a test flight.
Arapov said that since the drone was supposed to land on the runway in Protasovo, all emergency services were ready. “But it did not fly, it fell,” he said.
According to the spokesman for the governor, emergency services arrived at the scene in a matter of minutes and began inspecting the scene.
“Later, specialists from the Ministry of Defence, together with the employees of the Ministry of Emergencies, began to retrieve the drone. At the moment, as I know, it has been retrieved,” Arapov said.


The options on this page are broken down into three sections :
- Welcome message
This is the instant message that will be sent to new users who register
with this server.
- Registration
The inputs in this section all you to configure the message that
is sent to unregistered clients, whether the admin is notified of
new registrations, and the XML fields that are required from new users.
- Server vCard
This is an XML structure containing details of the server that gets
sent to the global Jabber user's directory. Only modify this if you
are familiar with the vCard format.


Click New Game to start
Arrow keys to walk
Hold down SHIFT to run
Face someone and press
SPACE to steal
Audio Volume
Brightness


A gene's co-expression partners are their neighbors in a co-expression network. In CoNekT we consider
direct neighbors the first-level neighborhood and 'neighbors of neighbors' the second level.
In graphs by default the second-level neighborhood is shown, with an option to only show the first level.


equals()
, compareTo()
or similar, that compare an object for equality
with itself.
The method contracts of these methods specify that such calls will always return
true
for equals()
or 0
for compareTo()
.
The inspection also checks
calls to Objects.equals()
, Objects.deepEquals()
,
Arrays.equals()
, Comparator.compare()
, assertEquals()
methods of
test frameworks (JUnit, TestNG, AssertJ), Integer.compare()
, Integer.compareUnsigned()
and similar methods.
Example:
class Foo {
boolean foo(Object o) {
return o.equals(o); // warning
}
boolean bar(String[] ss) {
return Arrays.equals(ss, ss); // warning
}
}
Use the option to report test assertions report only on non-extendable library classes (like String
) and primitive types.
This option can be useful, when testing equals()
methods.


|
|||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
Object org.apache.spark.streaming.receiver.Receiver<T>
public abstract class Receiver<T>
:: DeveloperApi ::
Abstract class of a receiver that can be run on worker nodes to receive external data. A
custom receiver can be defined by defining the functions onStart()
and onStop()
. onStart()
should define the setup steps necessary to start receiving data,
and onStop()
should define the cleanup steps necessary to stop receiving data.
Exceptions while receiving can be handled either by restarting the receiver with restart(...)
or stopped completely by stop(...)
or
A custom receiver in Scala would look like this.
class MyReceiver(storageLevel: StorageLevel) extends NetworkReceiver[String](storageLevel) {
def onStart() {
// Setup stuff (start threads, open sockets, etc.) to start receiving data.
// Must start new thread to receive data, as onStart() must be non-blocking.
// Call store(...) in those threads to store received data into Spark's memory.
// Call stop(...), restart(...) or reportError(...) on any thread based on how
// different errors needs to be handled.
// See corresponding method documentation for more details
}
def onStop() {
// Cleanup stuff (stop threads, close sockets, etc.) to stop receiving data.
}
}
A custom receiver in Java would look like this.
class MyReceiver extends Receiver<String> {
public MyReceiver(StorageLevel storageLevel) {
super(storageLevel);
}
public void onStart() {
// Setup stuff (start threads, open sockets, etc.) to start receiving data.
// Must start new thread to receive data, as onStart() must be non-blocking.
// Call store(...) in those threads to store received data into Spark's memory.
// Call stop(...), restart(...) or reportError(...) on any thread based on how
// different errors needs to be handled.
// See corresponding method documentation for more details
}
public void onStop() {
// Cleanup stuff (stop threads, close sockets, etc.) to stop receiving data.
}
}
| Constructor Summary | |
|---|---|
Receiver(StorageLevel storageLevel)
|
| Method Summary | |
|---|---|
org.apache.spark.streaming.receiver.ReceiverSupervisor |
executor_()
Handler object that runs the receiver. |
boolean |
isStarted()
Check if the receiver has started or not. |
boolean |
isStopped()
Check if receiver has been marked for stopping. |
abstract void |
onStart()
This method is called by the system when the receiver is started. |
abstract void |
onStop()
This method is called by the system when the receiver is stopped. |
scala.Option<String> |
preferredLocation()
Override this to specify a preferred location (hostname). |
void |
reportError(String message,
Throwable throwable)
Report exceptions in receiving data. |
void |
restart(String message)
Restart the receiver. |
void |
restart(String message,
Throwable error)
Restart the receiver. |
void |
restart(String message,
Throwable error,
int millisecond)
Restart the receiver. |
void |
stop(String message)
Stop the receiver completely. |
void |
stop(String message,
Throwable error)
Stop the receiver completely due to an exception |
StorageLevel |
storageLevel()
|
void |
store(scala.collection.mutable.ArrayBuffer<T> dataBuffer)
Store an ArrayBuffer of received data as a data block into Spark's memory. |
void |
store(scala.collection.mutable.ArrayBuffer<T> dataBuffer,
Object metadata)
Store an ArrayBuffer of received data as a data block into Spark's memory. |
void |
store(java.nio.ByteBuffer bytes)
Store the bytes of received data as a data block into Spark's memory. |
void |
store(java.nio.ByteBuffer bytes,
Object metadata)
Store the bytes of received data as a data block into Spark's memory. |
void |
store(scala.collection.Iterator<T> dataIterator)
Store an iterator of received data as a data block into Spark's memory. |
void |
store(java.util.Iterator<T> dataIterator)
Store an iterator of received data as a data block into Spark's memory. |
void |
store(java.util.Iterator<T> dataIterator,
Object metadata)
Store an iterator of received data as a data block into Spark's memory. |
void |
store(scala.collection.Iterator<T> dataIterator,
Object metadata)
Store an iterator of received data as a data block into Spark's memory. |
void |
store(T dataItem)
Store a single item of received data to Spark's memory. |
int |
streamId()
Get the unique identifier the receiver input stream that this receiver is associated with. |
| Methods inherited from class Object |
|---|
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
| Constructor Detail |
|---|
public Receiver(StorageLevel storageLevel)
| Method Detail |
|---|
public StorageLevel storageLevel()
public abstract void onStart()
store(data)
.
If there are errors in threads started here, then following options can be done
(i) reportError(...)
can be called to report the error to the driver.
The receiving of data will continue uninterrupted.
(ii) stop(...)
can be called to stop receiving data. This will call onStop()
to
clear up all resources allocated (threads, buffers, etc.) during onStart()
.
(iii) restart(...)
can be called to restart the receiver. This will call onStop()
immediately, and then onStart()
after a delay.
public abstract void onStop()
onStart()
must be cleaned up in this method.
public scala.Option<String> preferredLocation()
public void store(T dataItem)
dataItem
- (undocumented)public void store(scala.collection.mutable.ArrayBuffer<T> dataBuffer)
public void store(scala.collection.mutable.ArrayBuffer<T> dataBuffer, Object metadata)
dataBuffer
- (undocumented)metadata
- (undocumented)public void store(scala.collection.Iterator<T> dataIterator)
public void store(java.util.Iterator<T> dataIterator, Object metadata)
dataIterator
- (undocumented)metadata
- (undocumented)public void store(java.util.Iterator<T> dataIterator)
public void store(scala.collection.Iterator<T> dataIterator, Object metadata)
dataIterator
- (undocumented)metadata
- (undocumented)public void store(java.nio.ByteBuffer bytes)
bytes
- (undocumented)public void store(java.nio.ByteBuffer bytes, Object metadata)
bytes
- (undocumented)metadata
- (undocumented)public void reportError(String message, Throwable throwable)
public void restart(String message)
onStop()
and onStart()
) is performed asynchronously
in a background thread. The delay between the stopping and the starting
is defined by the Spark configuration spark.streaming.receiverRestartDelay
.
The message
will be reported to the driver.
message
- (undocumented)public void restart(String message, Throwable error)
onStop()
and onStart()
) is performed asynchronously
in a background thread. The delay between the stopping and the starting
is defined by the Spark configuration spark.streaming.receiverRestartDelay
.
The message
and exception
will be reported to the driver.
message
- (undocumented)error
- (undocumented)public void restart(String message, Throwable error, int millisecond)
onStop()
and onStart()
) is performed asynchronously
in a background thread.
message
- (undocumented)error
- (undocumented)millisecond
- (undocumented)public void stop(String message)
public void stop(String message, Throwable error)
public boolean isStarted()
public boolean isStopped()
public int streamId()
public org.apache.spark.streaming.receiver.ReceiverSupervisor executor_()
|
|||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |


Next Makkal Kural at Thirubhuvanai: Minister
by Special CorrespondentThe next Makkal Kural, a public grievance programme of the government, will be held at Thirubhuvanai in December, Social Welfare Minister M. Kandasamy said here on Monday.
Public should make use of the forum to air their grievances related to revenue and social welfare measures. Spot decisions would be taken based on the nature of issues raised, he said. He was inaugurating the 19th unit of Puducherry Co-operative Building Centre at Thirubhuvanai.


my games and demos
made using Game Maker Studio
Minigames and demos made using Game Maker Studio 1.4 and 2
The Great Adventures of Saku
"The Great Adventures of Saku" is an endless-runner mini-game in which you shoot mojitos to kill the pizza people.
Microwave Simulator
Born in a jam. In this game you have to affect the water particles in order to heat the food to the point your human wants.
Fire Wasteland
Fire Wasteland is a mini-game made for the uni in which you must slay the golem using only the directional keys.
Boxes
(technical demo)
An engine with an optimization that reduces the number of solid boxes in a room. It's useful for dynamic and proceduraly generated levels.
Tangram (demo)
A tangram puzzle engine in which the player is able to rotate and snap the pieces in place. It's easy to use for the developer.
contact me
fluent english / native spanish
email<EMAIL_ADDRESS>discord: luisaguirre#0285


Ben 10: Race Against Time
Ben 10: Race Against Time is a TV movie starring Graham Phillips, Christien Anholt, and Haley Ramm. Ben Tennyson returns home from summer vacation only to discover that a rapidly aging alien criminal named, Eon, is planning to use...


Mental Health Session
ScrollSpy:
My Feed
Remote Feeds
Dropdown
one
two
three
Mental Health...
With this app we are linking patient, therapist trainee, and supervisor all in one place!
Video Call Demo
Powered by Agora.io
Canvas :
Learn more
My Feed
...
Remote Feeds
...
Information
...
Information two
...
Information three
...


The MacroNutrient Calculator
Steps to Using the MacroNutrient Calculator
- Enter your daily calories (or use the 'Help Me Find My Daily Calories Needs' feature)
- Press the Calculate Button
- Use the sliders or presets to adjust the percentages
| Grams per Day | |||
|---|---|---|---|
| Carbohydrate: | Percentage: | - | |
| Protein: | Percentage: | - | |
| Fat: | Percentage: | - | |
| Total Percentage: 100% |
© MacroNutrientCalculator.com. All rights Reserved.


Conceptual & visual skills in web,
print & photography
hi, my name is rita ilchenko
and i am a designer
based in new york city, us.
I graduated with ba in
in graphic design
from Bernard Baruch
college (NYC).
i am always on lookout
for interesting
projects to work on.
i studied print design,
motion graphics,
ul, ux and tought
myself web design.
If you like me, email me. lets work together!


new year - old me and thedrunkfist podcast coming soon
New Year - Old Me and Podcast coming soon!
So, as January is in full swing I have decided to try and blog a bit more to go with my Instagram, Facebook and Twitter social media activity.
My first post of the year is a good place to look back at 2016 and reflect and plan for 2017.
I created a video slideshow of 2016 in review that shows me how well I did last year.
Weight was lost to a personal best level and I took up Muay Thai, BJJ and Yoga and things were positive despite it being a tricky year.
Just before Christmas I tailed off in terms of training and this year has started with a car accident among other things.
However, New Year - Old Me.
I intend to carry on with my martial arts and plan to only improve gradually this year just as I did last year.
No dad diets or plans that I will fail at as so many New Years have started off like.
I am a huge fan of podcasts and as an ex developer and devops nerd I have decided to try out creating my own podcasts.
As well as this website I am going to record, host and deliver podcasts to document my journey and chat all things health and fitness, diet and nutrition, MMA, Muay Thai, BJJ, Kettlebells and anything else that comes up.
I may even try and get some guests on.
Exciting stuff!
Happy new year!


Employment History
Jennison Associates LLC - Administrative Assistant/Finance Generalist 2013-Present
Provide administrative support to the Chief Financial Officer, an SVP and a VP in addition to general support to a 23 person Finance department. Manage company purchasing card and reconcile invoices on a monthly basis.Create and facilitate approval for purchase orders for new wireless devices, device upgrades, software and plan changes due to global travel for QMA via Prudential technology procurement portal Facilitate device troubleshooting and plan inquiries for QMA.
Blip Networks - Administrative Assistant/ Office Manager 2007-2013
Provided administrative support for the CEO and COO at this 50+ person company, including extensive domestic and international travel, calendar management, written correspondence, expense reports, and phone coverage, as well as general support for various staff.Performed HR functions (for one year) such as office orientation, maintaining employee contact sheet, setting up insurance benefits for new employees, updating changes in coverage due to address or policy changes, canceling insurance for terminated employees, and facilitating Cobra packages and payments Assisted Accountant (for two years) including monthly corporate AMEX bill reconciliation, tracking receivables, payroll and bill mailings
Two River Group - Administrative Assistant/Receptionist/Office Manager 2005-2007
Provided administrative support for Business Development team at fast paced venture capital firm, including extensive domestic and international travel, calendar management, written correspondence, expense reports, phone coverage Provided administrative support for Chief Financial Officer including monthly corporate AMEX bill reconciliation, payroll assistance, organization and mailing of corporate tax packages


|
SSD1306Ascii
|
The Arduino SSD1306Ascii Library is designed to display text on small monochrome OLED displays. These displays are available on ebay at very low cost.
The library is being developed using 0.96" and 1.3" displays with SSD1306 controllers. An initialization sequence for SH1106 controllers is included.
There are many existing full featured graphics libraries for these displays. The goal for this library is to only display text with minimum use of RAM and flash.
Here are key design goals:
Small size is the highest priority. Speed and features are lower priority.
Support multiple fonts. More than 40 fonts are included with this release. Fonts are only loaded if you reference them.
Support fixed width and proportional fonts.
Optionally magnify fonts by a factor of two.
Support 128x32 and 128x64 displays with I2C and SPI interfaces.
Use the standard Wire library for I2C. An optimization option is available to increase I2C performance.
Use the standard SPI library for hardware SPI.
Provide software SPI so the display can be connected to any digital pins.
A small AVR only I2C driver is available when no other I2C devices are used.
SSD1306Ascii can be installed using the library manager. Newer untagged versions may be available on GitHub.
You can manually install the SSD1306Ascii library by copying the SSD1306Ascii folder from the download package to the Arduino libraries folder in your sketch folder.
See the Manual installation section of this guide.
http://arduino.cc/en/Guide/Libraries
The library will be added to the Arduino Library Manager soon.
Scroll mode causes the display to scroll up when a new line is written to the display.
Scroll mode is configured by editing SSD1306Ascii.h.
If INCLUDE_SCROLLING is defined to be zero, new line will not scroll the display and code for scrolling will not be included. This option will save some code space and several bytes of RAM.
If INCLUDE_SCROLLING is non-zero, the scroll feature will be included.
Call SSD1306Ascii::setScrollMode() to change the scrolling mode.
The initial scroll mode is define by INITIAL_SCROLL_MODE in SSD1306Ascii.h
Scroll mode One of the following.
SCROLL_MODE_OFF - newline will not scroll the display or RAM window.
SCROLL_MODE_AUTO - newline will scroll both the display and RAM windows.
SCROLL_MODE_APP - newline scrolls the RAM window. The app scrolls the display window.
The SSD1306Ascii::clear() call will erase the display and start at the top of the display.
See the ScrollSpi and ScrollWire examples.
More advanced scrolling can be implemented using member functions such as SSD1306Ascii::scrollDisplay(), SSD1306Ascii::scrollMemory(), and SSD1306Ascii::scrollIsSynced().
Knowledge of the SSD1306 is useful for understanding advanced scrolling. See the SSD1306 data sheet.
Fonts are defined by .h files in the SSD1306Ascii/src/fonts folder. The fonts folder contains all fonts from openGLCD plus a number of extra fonts.
To select a font, call the SSD1306Ascii::setFont() member function like this.
Only fonts referenced in your program will be loaded into flash.
Here are symbols for fixed width fonts.
Adafruit5x7 cp437font8x8 fixed_bold10x15 fixednums15x31 fixednums7x15 fixednums8x16 font5x7 font8x8 lcd5x7 lcdnums12x16 lcdnums14x24 newbasic3x5 Stang5x7 System5x7 Wendy3x5 X11fixed7x14 X11fixed7x14B ZevvPeep8x16
Here are symbols for proportional fonts. Note that Iain5x7 and utf8font10x16 are proportional.
Arial14 Arial_bold_14 CalBlk36 CalLite24 Callibri10 Callibri11 Callibri11_bold Callibri11_italic Callibri14 Callibri15 Cooper19 Cooper21 Cooper26 Corsiva_12 Iain5x7 Roosewood22 Roosewood26 TimesNewRoman13 TimesNewRoman13_italic TimesNewRoman16 TimesNewRoman16_bold TimesNewRoman16_italic utf8font10x16 Verdana12 Verdana12_bold Verdana12_italic Verdana_digits_24
See allFonts.h for more information on adding a font.
The SSD1306Ascii::set2X() call doubles the size of characters. Each pixel becomes a 2x2 square. To return to standard size characters call SSD1306Ascii::set1X();
Several configuration options may be changed by editing the SSD1306Ascii.h file in the SSD1306Ascii/src folder.
These options are at the start of the file.
Please see the Classes tab for more information.
For I2C displays using the wire library Wire see the SSD1306AsciiWire class.
For I2C displays using the small AvrI2c class see the SSD1306AsciiAvrI2c class.
For SPI displays connected to the Arduino hardware SPI pins see the SSD1306AsciiSpi class.
See the SSD1306AsciiSoftSpi class for use of Software SPI.
If you wish to report bugs or have comments, open an issue on GitHub or send email to fat16. If possible, include a simple program that illustrates the bug or problem. lib@ sbcgl obal .net
A number of examples are provided in the SSD1306Ascii/examples folder.
To access these examples from the Arduino development environment go to: File -> Examples -> SSD1306Ascii -> <program Name>
Compile and upload to your Arduino to run the example.


Tačke Prekida tab
The Break Points tab shows you all of the
tačke prekida that you have set.
Break points can be set via the Historija and
Sajtovi tabs as well as the 'Add a custom HTTP break point' button on the
gornjeg nivoa alatna traka
Desni klik meni
Right clicking on a break point will bring up a menu which will allow you to:
Izmjeni...
This will bring up the 'Edit break point' dialog which allows you to edit the criteria that
defines the break point. Double clicking on the break point will also show this dialog.
Ukloni
This will remove the break point
Još vidjeti


public final class GeoHash extends java.lang.Object implements java.lang.Comparable<GeoHash>, java.io.Serializable
| Modifier and Type | Field and Description |
|---|---|
static long |
FIRST_BIT_FLAGGED |
| Modifier and Type | Method and Description |
|---|---|
int |
compareTo(GeoHash o) |
boolean |
contains(WGS84Point point)
find out if the given point lies within this hashes bounding box.
Note: this operation checks the bounding boxes coordinates, i.e. |
boolean |
enclosesCircleAroundPoint(WGS84Point point,
double radius) |
boolean |
equals(java.lang.Object obj) |
static GeoHash |
fromBinaryString(java.lang.String binaryString) |
static GeoHash |
fromGeohashString(java.lang.String geohash)
build a new
GeoHash from a base32-encoded String .This will also set up the hashes bounding box and other values, so it can also be used with functions like within(). |
static GeoHash |
fromLongValue(long hashVal,
int significantBits) |
static GeoHash |
fromOrd(long ord,
int significantBits) |
static java.lang.String |
geoHashStringWithCharacterPrecision(double latitude,
double longitude,
int numberOfCharacters)
This method uses the given number of characters as the desired precision
value.
|
GeoHash[] |
getAdjacent()
returns the 8 adjacent hashes for this one.
|
BoundingBox |
getBoundingBox() |
WGS84Point |
getBoundingBoxCenterPoint()
return the center of this
GeoHash s bounding box. |
int |
getCharacterPrecision()
Returns the number of characters that represent this hash.
|
GeoHash |
getEasternNeighbour() |
GeoHash |
getNorthernNeighbour() |
WGS84Point |
getPoint()
returns the
WGS84Point that was originally used to set up this.If it was built from a base32- String , this is the center point of
the bounding box. |
GeoHash |
getSouthernNeighbour() |
GeoHash |
getWesternNeighbour() |
int |
hashCode() |
long |
longValue() |
GeoHash |
next() |
GeoHash |
next(int step) |
long |
ord() |
GeoHash |
prev() |
int |
significantBits()
how many significant bits are there in this
GeoHash ? |
static long |
stepsBetween(GeoHash one,
GeoHash two)
Counts the number of geohashes contained between the two (ie how many
times next() is called to increment from one to two) This value depends
on the number of significant bits.
|
java.lang.String |
toBase32()
get the base32 string for this
GeoHash .this method only makes sense, if this hash has a multiple of 5 significant bits. |
java.lang.String |
toBinaryString() |
java.lang.String |
toString() |
static GeoHash |
withBitPrecision(double latitude,
double longitude,
int numberOfBits)
create a new
GeoHash with the given number of bits accuracy. |
static GeoHash |
withCharacterPrecision(double latitude,
double longitude,
int numberOfCharacters)
This method uses the given number of characters as the desired precision
value.
|
boolean |
within(GeoHash boundingBox)
returns true iff this is within the given geohash bounding box.
|
public static final long FIRST_BIT_FLAGGED
public static GeoHash withCharacterPrecision(double latitude, double longitude, int numberOfCharacters)
public static GeoHash withBitPrecision(double latitude, double longitude, int numberOfBits)
GeoHash
with the given number of bits accuracy. This
at the same time defines this hash's bounding box.public static GeoHash fromBinaryString(java.lang.String binaryString)
public static GeoHash fromGeohashString(java.lang.String geohash)
GeoHash
from a base32-encoded String
.public static GeoHash fromLongValue(long hashVal, int significantBits)
public static java.lang.String geoHashStringWithCharacterPrecision(double latitude, double longitude, int numberOfCharacters)
public GeoHash next(int step)
public GeoHash next()
public GeoHash prev()
public long ord()
public int getCharacterPrecision()
java.lang.IllegalStateException
- when the hash cannot be encoded in base32, i.e. when the
precision is not a multiple of 5.public static GeoHash fromOrd(long ord, int significantBits)
public static long stepsBetween(GeoHash one, GeoHash two)
one
- two
- public GeoHash[] getAdjacent()
public int significantBits()
GeoHash
?public long longValue()
public java.lang.String toBase32()
GeoHash
.java.lang.IllegalStateException
- when the number of significant bits is not a multiple of 5.public boolean within(GeoHash boundingBox)
public boolean contains(WGS84Point point)
GeoHash
s special abilities.spublic WGS84Point getPoint()
WGS84Point
that was originally used to set up this.String
, this is the center point of
the bounding box.public WGS84Point getBoundingBoxCenterPoint()
GeoHash
s bounding box. this is rarely
the same point that was used to build the hash.public BoundingBox getBoundingBox()
public boolean enclosesCircleAroundPoint(WGS84Point point, double radius)
public GeoHash getNorthernNeighbour()
public GeoHash getSouthernNeighbour()
public GeoHash getEasternNeighbour()
public GeoHash getWesternNeighbour()
public java.lang.String toString()
toString
in class java.lang.Object
public java.lang.String toBinaryString()
public boolean equals(java.lang.Object obj)
equals
in class java.lang.Object
public int hashCode()
hashCode
in class java.lang.Object


http://christianhall.me/redux-101/
Christian Hall
Lead Developer @ Good
Do I need Redux to write good React apps?
Should I switch from (insert framework) to React + Redux right now?
Will my app/startup/life fail if I'm not using Redux?
Use what works for you. If you like some of the ideas behind Redux, use it or find a way to use the ideas with your stack.
Single source of truth
State is read only
Changes are made with pure functions
Plain JavaScript Objects
Only source of information for the store (via dispatch)
Must have a type
Action creators are just functions that return actions
{
type: ADD_TODO,
text: 'Build my first Redux app'
}
Specifiy how app's state changes in response to an action
(previousState, action) => newState
Must be pure functions
Can be composed to manage different parts of state tree
function todoApp(state = initialState, action) {
switch (action.type) {
case ADD_TODO:
return Object.assign({}, state, {
todos: [
...state.todos,
{
text: action.text,
completed: false
}
]
})
default:
return state
}
}
Holds application state
Allows access to state via getState()
Allows state to be updated via dispatch(action)
Handles low level listeners
Requires react-redux
for bindings
Component hierarchy should match state tree design
Container and presentational components
fin


Zog was a top elf. His job was to sort the children's presents. He kept a long list of children and gifts. Zog kept the presents in stacks. There were stacks of gifts for kids under ten and stacks for big kids. Zog got his fork-lift truck and went to lift a stack of presents into Santa's sack but the truck hit the stack. The stack toppled and hit the next stack and that stack hit the next stack and so on. The gifts fell and got muddled up. Zog looked on, helpless. He felt bad. He went to tell Santa. Was Santa cross" No. Santa went to help Zog. Zog and Santa got the gifts back into the correct stacks. Next, Zog and Santa loaded the gifts into sacks and lifted the sacks onto Santa's sled. "Top job, Zog," said Santa with a grin. Off went Santa and Zog to deliver the children's presents.
in-context


Services
- Handle most of the business logic of Angular2 apps
- Communicate with the backend to load/store data
- Much the same as AngularJS services
Services
@Injectable
export class HeroService {
static get parameters() {
return [[BackendService]];
}
constructor(backendService) {
this._backend = backendService;
}
getHeroes() {
return this._backend.get('/api/v1/heroes');
}
}


Register
First name:
Last name:
Male
Female
Other
Email:
Password:
Birthday:
Month
Jan
Feb
JMar
Apr
May
Jun
Jul
Aug
Sep
Oct
Nov
Dic
Month
Jan
Feb
JMar
Apr
May
Jun
Jul
Aug
Sep
Oct
Nov
Dic
Month
Jan
Feb
JMar
Apr
May
Jun
Jul
Aug
Sep
Oct
Nov
Dic
I agree to the terms and Conditions


Frame
Simple examples
5-cell series
8-16-cell series
24-cell series
120-600-cell series
Others
View
Control:
Auto
Stop
3D move
4D move


| 7.6.0 |
S3 Bucket Entry
|
| 7.6.1 |
More Configuration
|
| 7.6.2 |
S3 Harvesting
|
| 7.6.3 |
Specifying Entry Types
|
| 7.6.4 |
S3 Tools
|
To create a new S3 entry go to the File->Pick a Type menu and select "AWS S3". In the create form entry the S3 URL, a name and an optional description:
After adding the entry you can edit it to configure how the S3 buckets are displayed.pattern;template;date formatand is used to match against a folder or file name. The pattern needs to contain "(...)" groups. If it matches then the matching groups are extracted and the template (the 2nd part of the 3-tuple) is used to create a date string. This date string is then parsed by the date format.
key1=value1 key2=value2 ...If it is a .txt file then the first line is the key that is matched against the S3 folder names and the rest of the file is a wiki display template:
key_or_pattern wiki text ...
For the NEXRAD example we will upload a nexrad.csv file. This has the following structure:
id,fullname,lat,lon KAPD,KAPD - Fairbanks/Pedro Dome,65.035,-147.50167 KAEC,KAEC - Fairbanks/Nome,64.51139,-165.295 KACG,KACG - Juneau/Sitka,56.85278,-135.52917 KAIH,KAIH - Anchorage/Middleton Island,59.46139,-146.30306 ...The first column is the station ID and this is used to match up (either exact or pattern) with the S3 folders. Upload the nexrad.csv file and select Alias and Exact: :p :p Now, the station folders have the full name. Next, upload the same file and select "Location". This adds the spatial metadata to the station folders.
Note: we have combined the aliases with the locations. The aliases file could have been a properties file: nexrad_aliases.properties file.
Next, we want to specify the wiki template to be used for the folder that contains the stations, i.e., the year/month/day folder. Here we will upload this nexrad_templates.txt file. It has the format:
^\d\d/\d\d$The first line is a pattern that matches NN/NN, i.e., the month/day folder names. The remainder of the file is the wiki text to be used for the folders that match the pattern. :p Upload this file, select "Template" and for match type select "Pattern". Now, for the day folder we should have: :p :p And finally, we want to show the files as "Level 3 Radar" files, a file format that RAMADDA provides. To do this go to the Add Properties menu and under Miscellaneous select "Entry Type Patterns". This property allows you to specify an entry type (e.g., Level 2 Radar File) and one or more patterns to match. For the NEXRAD data collection we know that all of the files are of this type so we specify as a pattern "file:" :p :p Now, with that the files should be shown as this entry type: :p :p+section title="NEXRAD Stations - { {name entry=parent} } { {name} } { {name entry=grandparent} }" +inset left=20px right=20px { {map listentries=true hideIfNoLocations=true} } ...
sh s3.sh -help Usage: S3File <-key KEY_SPEC (Key spec is either a accesskey:secretkey or an env variable set to accesskey:secretkey)> <-download download the files> <-nomakedirs don't make a tree when downloading files> <-overwrite overwrite the files when downloading> <-sizelimit size mb (don't download files larger than limit (mb)> <-percent 0-1 (for buckets with many (>100) siblings apply this as percent probablity that the bucket will be downloaded)> <-recursive recurse down the tree when listing> <-search search_term> <-self print out the details about the bucket> ... one or more bucketsAnother utility is provided in the RAMADDA repository runtime at the /aws/s3/list entry point. This provides an interface to the above tool to do a recursive listing of a bucket store. Check it out on https://ramadda.org/repository/aws/s3/list. Try this out with an example:
s3://first-street-climate-risk-statistics-for-noncommercial-use/


StoryTime Adventure!
Log In
Sign Up
Log In:
×
Email
Done!
need a valid email!
Password:
Done!
You Must Add a Password!
Sign-Up
×
Email
Done!
need a valid email!
Password:
Done!
You Must Add a Password!
First Name:
Last Name:


Hello,
I'm a full-stack developer, passionate about front-end mobile design. My work begins with Design Thinking, UX planning, and goal setting to achieve new business goals and user goals alike.
Recent Projects
Here are some web apps I helped to plan, design, build, and launch.
-
- Acorn Health
- Connecting families with an ABA network to find care for children with autism.
- Features:Zip & Geolocation Search, State & Local Resources
- Role:Full-Stack Developer
- Tools: HTML, Gulp, SASS, JS, Timber
-
- Ideal Cap Group
- A fresh look for a family-owned firm with decades of investment experience.
- Features:UI Animation, Portfolio, Property Map
- Role:Front-End Developer
- Tools: React, Gatsby, JSX, SASS, JS
-
- FlingGolf
- Getting today's generation to try this sport's new spin on traditional golf.
- Features:Custom eCommerce, Course Locator, Event Calendar
- Role: UX Designer, Front-End Developer
- Tools: HTML, SASS, Shopify, ThemeKit, Liquid
-
- Long Wharf Capital
- Building trust between real estate investors and this Boston-based team.
- Features:UI Animation, Portfolio, CMS, Site Search
- Role: Mobile UI Designer, Full-Stack Developer
- Tools:HTML, Gulp, SASS, JS, Timber
-
- Primary360
- Transforming how an integrated marketing agency presents itself online.
- Features:UI Animation, Portfolio, Blog, Bespoke Theme
- Role: UX Designer, Full-Stack Developer
- Tools: HTML, Gulp, SASS, JS, Nunjucks
-
- Woodmont Properties
- Promoting partnership for a real estate company now in business over half a century.
- Features:Property Filter, CMS, Bespoke Theme
- Role: Mobile UI Designer, Full Stack Developer
- Tools: HTML, Gulp, SASS, JS, Timber
-
- We Are Merrimack Valley
- Bringing economic development to the region with real estate listings, entrepreneur interviews and other resources.
- Features:Property Search / Filter, .CSV Data Import, Business Toolkit
- Role: Mobile UI Designer, Full Stack Developer
- Tools:HTML, Gulp, SASS, JS, Timber, EagleView API
Past Experience
-
2007 - 2011
I got started as a freelance designer and web developer in 2007, networking and learning more new skills in the field year after year. -
2012
For the Summer I was an ID Tech Camps instructor of Photography and Web Development courses to kids and teens on the MIT campus in Cambridge, MA. -
2013 - 2020
My first agency experience began at Primary Design as a Junior Developer. I learned so much while too helping Primary grow over seven years. -
2016
As my expanding role in the planning of Web projects matured, I earned an official title of (the agency's first) UX Designer! -
2018
I jumped from building single page applications with Meteor to pursue the more popular JavaScript framework, React. -
2020
Today, I freelance full-time as a UX Designer & Front-End Developer, seeking future work with a fun and talented digital product team.
Dev Skills
Full Stack
Handling server-side duties like hosting, DNS, databases, SSL certificates and SEO best practices has been my job for over 50 web products.
GIT & Github
I've pushed over 350 commits in the past year. I know my way around Terminal, Bitbucket.com, GitHub.com and Git to collaborate with a team of developers.
HTML5
I enjoy coding with semantic HTML5 — it's more meaningful to my fellow developers and better-suited for modern devices, browsers and search engines.
SASS
Who knew styling could be so much fun? Not only does SASS make my days coding easier, it's helped me improve as a front-end developer.
Task Runners
Gulp, Webpack etc. have saved countless hours from my development workflow. They can be used to live-update, prefix, preprocess, concatenate, minify, template, theme, and more.
Design Skills
User Experience
Learning and applying UXD has transformed my web design workflow. Research and planning can align the objectives of a product's stakeholders with its users.
User Interface
A good UI begins with competitive research and plenty of sketching. Understand the problem and let usability testing solve the rest. Last but not least, apply strong visual design.
Responsive / Web
Always mobile-first, BrowserSync device testing aids in my quality assessments. When I'm crafting web components and design systems, no screen size goes overlooked.
Graphic
While majoring in Visual Communications I gained a deeper understanding of graphic design and its principles. I'm still learning and use Adobe CC's design apps on a weekly basis.
Motion
Since drawing flipbooks as a kid I've always dabbled in animation. Today my motion design chops apply to projects in Adobe Animate, Premiere Pro, CSS3 and JavaScript.
Testimonials
Here are some web apps I helped to design, build, launch and maintain.
-
Niko has a natural interest in learning new things and creative problem solving. He is open to new ideas, listens to feedback and continuously pushes for a more positive user experience.
Victoria Tran
-
He is a level head, from discussing the rationale behind development standards to providing valued feedback on design prototypes.
Nelson Lourenço
-
Niko opened our eyes to the creative possibilites and his up-to-date knowledge excited us. He delivered a great looking site and continually offers suggestions for better functionality. He knows his stuff and continues to learn.
Phillip Dunn
-
He's a very organized, determined and intelligent guy who brings a growth mindset to every assignment, and rises to meet new challenges.
Michael Bourne
-
Niko works well independently as well as with a group. When a task was delegated to him, he would extend himself further; seeing if there was anything else he could do to help out. It's nice to work with someone who genuinely cares about what they're doing and the mark they're leaving behind. Simply put, this is a guy you want on your team because day in and out, he gives it his all.
Kwadwo Amo-Mensah


A real-time schedule app, built using AngularJS & Firebase. Open in 2 different browsers to experience the magic.


Politico
Sign out
Admin Dashboard
Political Parties
Create party
Edit party
Delete party
Political Offices
Edit office
Remove office
Add new office
Office name
President
Governor
Senator
House of Representatives
Office Type
Federal
Congress
State
Create Office
Cancel


Internet Relay Chat and Screen
Internet Relay Chat (IRC) hs been around since 1988 and was created by Jarkko Oikarinen.
IRC was borne out of the need to have a real time communication system while using an operating system to communicate with other users.
IRC is an open protocol that uses Transmission Control Protocol (TCP).
You can read more about IRC in the official Internet Relay Chat Protocol RFC 1459.
During an IRC session, client will send 1 line messages to a server.
I am mostly a terminal user so my ideal irc client would be terminal based.
IRSSI
IRSSI is an IRC client that you can use in Linux, Mac and Windows.
Since I primarily work in Mac OS X I will show how I setup IRSSI on the Mac but you can find you particular install and setup directions at irssi.org/download official website.
IRSSI Mac Setup
Now with that let us get irssi up and running in a terminal environment.
If you have Homebrew installed you can install irssi in one command like this:
brew install irssi
I already have irssi installed in my Macbook Pro as you can tell:
Starting an IRSSI session
You can simply type irssi
in a terminal session after installing irssi and you will see a screen like this:
Notice that we are being prompted for a status
since we haven’t really connected to anything yet.
Starting a screen session
Instead of simply typing in irssi
in a terminal let us first start a screen session.
Screen
is a terminal multiplexer that has been around for a long time like over 30 years and has many possible uses.
The nice thing about using screen with irssi is that we can keep a long running session that won’t be interrupted if we decide to logoff of our current computer session and we can detach it for later use.
With that being said if you are already on a mac then you will already have it installed most probably.
We can kill our current irssi session by simply typing /exit
or /EXIT
in the status prompt in the bottom.
Let us create a new screen session like this:
screen -S irc-chat
We named our screen session irc-chat
Now we will simply type in irssi
like we did before except we now have a screen session running as well.
Connecting to a network
In order for us to do anything useful we need to connect to an actual IRC Network.
For the purposes of this blog post we will connect to the Mozilla IRC Server of irc.mozilla.org
.
Using the /help in irssi
You can use the /help
command in irssi to understand each command and by the way each command begins with the /
character in an irssi session.
Let us connect to the irc.mozilla.org
irc server with the following command:
/connnect irc.mozilla.org
Once connected you will see a screen like this:
We can type the following command to see a list of all available Channels in the particular IRC Server we are connected to:
/LIST -YES
Notice that we put -YES
after our command because of a particular warning prompt you get with the /LIST
command
Connecting to Rust
Since we are in a screen session we need to type in Control Character A then [
or C-a [
so that we can scroll back and look at channels.
Reading help menu for /channel
command
Let us read some help documentation for the /channel
command:
There is quite a bit of options but we will simply type in:
/join #rust-servo
To join the #rust-servo
channel.
Now that we have joined we should see a session like this:
Setting a nickname
You can set a nickname by typing in:
/set nick <nick_name>
We can leave an IRC channel by simply typing in /leave
and we will leave the channel.
List names of current users in channel
We can see a list of current users in a channel by typing in
/names
You will see a screen like this:
You won’t see any information about the user until you exit the channel so don’t be alarmed:
Private Messenging
You can privately message a user by using there nickname like this:
/msg comey Hello There My friend!
Leaving an IRC Server
We can simply type in:
/quit
to leave the IRC Server.
Detach screen session
Remember that we created a screen session if we want to detach from our current running session we simply type:
Ctrl+a d
Listing screen session
If we don’t remember what we called our screen session then we can simply type in:
screen -ls
and we will see something like this in the terminal:
Reattaching a Screen session
We can simply type in:
screen -r irc-chat
and we will be reattached to our previous irc session:
There is much more you can do with irssi/screen than I have mentioned here and I would suggest trying it out on your own.
Twitter & Github Account
Please follow me at jbelmont @ github and jbelmont80 @ twitter
Feel free to leave a comment if you like.
Until Next Time :)


This module segments a marked object (creating a graphical object) within an input image.
Then the module will classify either the entire original image or the segment created in the first step.
Steps to run the algorithm:
- Select an image to be analyzed.
- The foreground/background annotation tooltip can be found on the top-right of the module image viewer.
Mark the part of the image to be segmented with foreground line(s) annotation(s).
Mark the image with background annotations around the object to be segmented.
- Optional: Select which deep classifier to use, whether to segment the image, the segmentation quality,
and whether to classify the entire image or the segmented object instead.
-
Press the 'Run' button. Analysis may take some time depending on the image and segmentation
quality.
-
Results are given in visual and table formats, depending on whether the segmentation and
classification functionalities respectively were enabled in the options.
Author(s): Dimitrios Trigkakis, Justin Preece
Assisted by CyVerse: Blake Joyce, Phil Daly


Use the form below to book your course.
Does the quotation above accurately reflect your choice of arrangements including course, dates, and accommodation? Please type "Yes" or otherwise give details
Is there anything else you would like us to know?
Type your name below to confirm that you have read and understood our privacy policy and our terms and conditions.


If present, side nav bars can be pinned for permanent display or float temporarily as overlays. Side navs can be positioned on the left or right side of the screen.
The content appearing in the left nav is ideally navigation- or identity-based. Right nav content should be secondary to the main content on a page.
Side nav bars may be pinned for permanent display, or they can float temporarily as overlays. Temporary nav drawers overlay the content canvas; whereas pinned nav panels are situated alongside or below the content canvas.
Screen size can determine whether a panel is pinned or an overlay. With sufficient space, a panel can be pinned and content adjusted responsively. With insufficient space, a panel has to be an overlay.


|
entity - name of entity to be positioned
x# - x co-ordinate that entity will be positioned at y# - y co-ordinate that entity will be positioned at z# - z co-ordinate that entity will be positioned at global (optional) - true if the position should be relative to 0,0,0 rather than a parent entity's position. False by default. |
|
Positions an entity at an absolute position in 3D space.
Entities are positioned using an x,y,z coordinate system. x, y and z each have their own axis, and each axis has its own set of values. By specifying a value for each axis, you can position an entity anywhere in 3D space. 0,0,0 is the centre of 3D space, and if the camera is pointing in the default positive z direction, then positioning an entity with a z value of above 0 will make it appear in front of the camera, whereas a negative z value would see it disappear behind the camera. Changing the x value would see it moving sideways, and changing the y value would see it moving up/down. Of course, the direction in which entities appear to move is relative to the position and orientation of the camera. See also: MoveEntity, TranslateEntity, PositionMesh. |
|
; PositionEntity Example
; ---------------------- Graphics3D 640,480 SetBuffer BackBuffer() camera=CreateCamera() light=CreateLight() cone=CreateCone( 32 ) ; Set position values so that cone is positioned in front of camera, so we can see it to begin with x#=0 y#=0 z#=10 While Not KeyDown( 1 ) ; Change position values depending on key pressed If KeyDown( 203 )=True Then x#=x#-0.1 If KeyDown( 205 )=True Then x#=x#+0.1 If KeyDown( 208 )=True Then y#=y#-0.1 If KeyDown( 200 )=True Then y#=y#+0.1 If KeyDown( 44 )=True Then z#=z#-0.1 If KeyDown( 30 )=True Then z#=z#+0.1 ; Position cone using position values PositionEntity cone,x#,y#,z# RenderWorld Text 0,0,"Use cursor/A/Z keys to change cone position" Text 0,20,"X Position: "+x# Text 0,40,"Y Position: "+y# Text 0,60,"Z Position: "+z# Flip Wend End |


{% extends '__layout__.html' %} {% block title %}Edit Lesson{% endblock %} {% block header %} {% endblock %} {% block navbar %} {% include 'tutor/navbar.html' %} {% endblock %} {% block breadcrumbs %}
{{ error }}
You've made your changes and your ready to submit the form? This could send automatic emails to all the new students you've added to this lesson as well as send emails to those student's you've removed.