I would like to write a console app with text UI in D. I looked at curses, but it seems that it works only on unix. Are there any cross-patform alternatives?
My terminal.d could be used as a foundation for a TUI library.
https://github.com/adamdruppe/arsd/blob/master/terminal.d
It has no required dependencies, so you can simply download that one file and start building with dmd yourfile.d terminal.d. Here's an example program getting input: http://arsdnet.net/dcode/book/chapter_12/07/input.d
You can also use terminal.moveTo(x, y); terminal.color(Color.green, Color.black); terminal.writef("something"); terminal.flush(); and such to move and draw.
Look for version(Demo) in terminal.d itself for a main which handles all kinds of input events, including mouse events.
While terminal.d mostly offers lower-level functions (its main high level function is terminal.getline, great for line based apps but not TUIs), it should give all the foundation needed to write a little text widget library.
and I think someone might have done that once but I don't recall where.
terminal.d works on Windows and Posix systems, for the most common terminals like xterm. ncurses is more comprehensive and probably has fewer bugs on more obscure targets but terminal.d, being a single file, is easier to build.
That was true long ago. However, ncurses is known to work nicely on Windows as well. The easiest way to build it on Windows is inside the MSYS2 shell. There is really no other cross-platform alternative to Curses (find out why they named the project "curses" and you will find why there is no good alternative).
Related
Terminal texteditors like emacs,vim,joe or even nano have the ability to display arbitrary UI elements inside a command line without completely rewriting the whole UI every single time, but overwriting what currently is their UI.
With regular output streams, you can only use the return character '\r' to jump to the beginning of the current line of output and write over it, but from what I found you can not jump up multiple lines, cout << "\r\r\r\r\r\r"; has the same effect as cout << '\r', so everything followed by a newline is apparently cast in stone.
Other applications do something similar, for example $dpkg-reconfigure ca-certificates on Ubuntu or the aptitude graphical package manager. They also draw outlines for UI elements, which are probably just special characters. But still, they'd have to overwrite multiple lines of console output.
How do they do that? Is the behaviour portable to Windows platforms?
You'll find that these programs depend on a library called ncurses:
http://en.wikipedia.org/wiki/Ncurses
There are builds available for almost all operating systems.
curses is a unix library that lets you manipulate the contents of a terminal at arbitrary positions. ncurses is a free, vendor-independent version of curses, and the curses library used on linux.
dpkg-reconfigure uses dialog that builds on top of curses and provides user interface widgets instead of raw terminal access.
ncurses includes the extensions "menu", "forms", "panel" that you could use to implement user interface widgets yourself, though it gets very complex very quickly if you go that route.
Regarding windows, there is pdcurses that runs natively in the "dos box" terminal. You can write portable programs that use pdcurses on windows and ncurses on linux if you restrict yourself to the common subset. Alternatively, you can use ncurses on windows using cygwin.
Another alternative for windows might be Borlands TVision - if you can find an old version of Borland's turbo pascal or c++ compiler, they included a complete application framework for text user interfaces called TVision. Not sure if the code generated by these would still run on modern windows versions, though.
The console follows a specification:
https://www.xfree86.org/current/ctlseqs.html
This is similar to a client/server. If you application (the client) follows the same specification, it can communicate with the console via the standard input/output to draw anything its wants.
There are many things in the specification:
Clear a specific line.
Move the cursor
Set background/foreground color.
Set style: bold, dim, underlined, blink, ...
Request sending mouse events, receive mouse events.
Configure the console to nowrap/wrap lines.
Configure the console to use the "alternate" screen.
etc..
I've been away from GUI programming for quite some time so please pardon my ignorance.
I would like to attempt the following:
Write a Mac OSX app but still be able to port to Win/Linux (i.e. C++ core with Obj-C GUI)
Avoid Qt/other toolkits on OSX (i.e. talk to Cocoa directly - I feel that many Qt apps I use stick out like sore thumbs compared to the rest of my system)
Not as important, but it would be nice to avoid Visual Studio if it means I can have the freedom to use newer C++ features even on Windows if they help create better code.
I believe this configuration might get me what I'm looking for:
Core C++ Static Library
OSX GUI (Cocoa)
Windows GUI (Qt+MinGW?) OR (no new C++ features, Visual Studio + ManagedC++/C#/????)
Linux GUI (Qt)
Once again, sorry for my ignorance but is this possible? Is this sane? Are there any real-world open source examples accomplish something like this?
There is quite a few OS X applications that have completely custom-designed looks that don't use very many stock controls. iStat Menus comes to mind, but there are many other examples. They still look good, but it's done by manually designing them to look good and to "mesh" with the overall look of OS X applications. Even their preferences pane doesn't use stock buttons.
Thus, you can go quite far using Qt, you just have to pay close attention to what you're doing - similarly to the way other developers are paying close attention even when using Cocoa. You'll find that Qt's controls offer functionality often above and beyond what's offered in Cocoa.
That said, on OS X sometimes you may need to run some native code that expects a CFRunLoop to be present. It's good to know that Qt's event loop already spins a runloop for you, so as long as you have an event loop spinning in a given thread, you can use runloop-based code - the default runloop is provided by Qt's implementation of QEventDispatcher (somewhere in its guts). For non-gui threads, the unmodified QThread does it for you. This is useful for using asynchronous IOKit functionality, for example. Another answer of mine presents some Cocoa mouse event grabbing code. A previous version that used Carbon can be found in the edit history of that answer.
Same goes for Windows: Qt runs a message sink for all top-level windows it owns, and you can integrate native controls/windows using qtwinmigrate. You can also integrate ActiveX controls using the Active Qt framework.
Well I think you should try Qt even on OSX. Qt allows native/custom look of applications (those cases you mentioned are probably bad examples - you probably haven't noticed that lots of other applications also use Qt).
Tools I usually use for multi-platform development:
C++ (now C++11 since all major compilers more or less support it)
Boost
Qt
CMake as build system generator
If you use this tool-set you can choose whichever platform you like for development and still be multi-platform without extensive work on the other platforms.
I have a lot of simple C++ programs that I've written in XCode, using OpenGL and Glut to visualise scientific data. It works very well, but there is one minor annoyance: every time I run one of the binaries from outside of XCode, it opens a Terminal window. This means I get a crusty build-up of Terminal windows that has to be cleaned up after use.
Is there a way to prevent this from happening? I'm hoping for a quick solution to a very minor problem, so anything that requires me to learn Objective C or some fancy GUI creation tool isn't what I want. I just want to know if there's a way to compile my existing C++ Glut apps in such a way that the terminal window won't appear when you click on the icon.
Sort of... Basically, you need some kind of OS X wrapper to contain the binary. You can do this with Automator or AppleScript or with a tool like DropScript, which is designed to encapsulate unix binaries.
Otherwise, the solution for this would be to create a minimal Objective-C program and then she'll out the unix binary from within it, so that when it terminates it doesn't leave any residue.
Edit: This question has been answered indirectly in the comments (using GLUT to avoid the need for either) but because its not posted as an answer, I cannot "accept" it although my issue is solved.
I have a cross platform OpenGL application, written in C++, that (on Mac OS X) uses Carbon for the window creation and message pump (Think...NeHe Lesson 1). Recent changes to my code utilizing C++11 features has made it incompatible with the GCC that comes bundled with XCode.
All of my attempts to use systems like MacPorts, HomeBrew, etc... have failed for different reasons (Mostly due to my need to compile 32bit for Carbon support). I was originally going to ask if anyone had a better solution for installing an updated G++ in Mac OS X 10.8.
That seems like a short sighted solution (at some point, I will need to upgrade to Cocoa and 64bit) so my question has evolved to asking what would be the most simple way to have my existing (very large) application utilize Cocoa for this task rather than Carbon?
I have all of the "Carbon Code" in its own separate .cpp/.h file, which has only two functions, one to create an OpenGL window, and one that is a message pump that uses ReceiveNextEvent.
Edit:
To be clearer, I am looking for the best way to design (more or less) a drop in replacement for my existing Carbon window creation, and message pump functions, but in Cocoa. I understand that being a different API, using different language concepts, that a simple one to one command replacement will not suffice. My existing code has a source code file for Mac that has two functions which perform core tasks (with Carbon) that I call, InitWindow, and DoEvents. These create the window, and cycle through the pending events respectively. It is my goal to replace this source code file with one that uses Cocoa, exposing the same functions so there is little to no modification of my core code.
What would be the best way to achieve my goal? I am not familiar with Cocoa and Obj-C is alien to me.
Going to Cocoa 64-bit definitely sounds like a great idea. And I recommend using some of the native UI if you want to make your users happy, too.
The easiest thing to do would be to create an NSWindow with an NSOpenGLView in it. You can either do that in Interface Builder, or in code. It's probably best to do it by creating a new Cocoa app using Xcode's template (File > New Project > Cocoa App). That will give you a window by default. You can open it in Interface Builder and add an NSOpenGLView to it. You can make the view a custom subclass of NSOpenGLView, and add your event handling to it. See the docs for NSResponder for more information on how Cocoa dispatches events.
I am looking to get started with some 3D programming in C or C++. The problem I have is that it seems like the only tutorials I can find for Mac OS use objective C and Cocoa frameworks. I want to obtain the same environment as Windows users, more or less.
If I try to use a text editor and g++ compiler, I am missing headers, but, if I try to use Xcode, I am forced to grapple with Cocoa, which is frustrating to me. I don't really see any reason why the OpenGL/GLUT that comes pre-installed on Mac should force me to use Xcode, but it seems I can't get the header files without it.
How can I get through all of the Apple 'developer friendly' interfaces to write some old-fashioned code with full cross-platform portability?
Some portion of Objective-C is inevitable if you want to use the latest benefits of the OSX/Cocoa. The easiest way to port an existing application to MacOS would be the following:
Write the "bare bones" nibless application in Objective-C. It would only be a single AppDelegate class and a little setup in the main() function
Add the custom NSGLView descendant in your window which you create in the AppDelegate's didFinishLaunching event handler
Setup the CVDisplayLink and rendering callback in the NSGLView initialization
Use your existing OpenGL rendering code in the CVDisplayLink's callback
Now for the interesting part: where to get all of this ?
Surprisingly, a good nibless application sample is the UI for OSX's port of QEMU (yes, the emulator). Also the Apple's official GLEssenstialPractices demo shows all the information you need to set up OpenGL rendering pipeline. All the rest is up to you.
The detailed and modern introduction to system-level OSX programming can be found in the "Advanced Mac OS X Programming" book by Mark Dalrymple. It explains many things and after reading all of this I've understood most of the design decisions in the OS (it really makes you accept all the "non-standard" things if you think from the performance viewpoint).
To get through the "nibless" programming I would recommend you to read the blog posts like this one http://blog.kleymeyer.com/2008/05/creating-cocoa-applications-programatically-ie-nib-less/ The google search helps a lot.
The same tricks apply to the CocoaTouch/iOS and there are a lot of questions answered on SO, like this one Cocoa touch/Xcode - generating NIB-less graphics context
If you want to create cross-platform applications you could create a project with the Command Line Tool template.
Next, import the OpenGL and GLUT framework. This will get you a "blank" C++ project with the required OpenGL and GLUT headers.
Lighthouse 3D gives you some tips about portability and how to initiate your first project.
http://www.lighthouse3d.com/tutorials/glut-tutorial/initialization/
I have created a software layer (named cocoglut) that allows the translatation of basic or essential GLUT calls to COCOA. This library allows creating/destroying windows and register callbacks from a C/C++ application, just by using GLUT calls, without the need for nib files or for XCode project files (and can be compiled from the command line). This option uses full retina display resolution. The source is on GitHub.