How draw a line in a window with wxWidget with erlang? - erlang

I try to draw a line in a window with wxWidget in Erlang. I tried:
wx:new(),
Frame = wxFrame:new(wx:null(), ?wxID_ANY, "Hello"),
wxDC:drawLine(50,50),
I get an error:
undefined function wxDC:drawLine/2
I read the documentation here, but I don't understand how to do this:
http://www.erlang.org/doc/man/wxDC.html#drawLine-3

X Windows programming isn't quite that simple, and I'm not quite sure how you are expecting to draw a line with parameters like [50, 50], that's at best a point, and a line needs 2 points, and wxDC:drawLine needs to know where to draw the line too, because you could have many frames.
You can create a frame like this, yes (used -1 instead of the macro because I'm using the shell here):
Wx = wx:new().
Frame = wxFrame:new(wx:null(), -1, "Hello").
Now the important bit, you can't just draw on the frame, you have to register a callback to handle REdrawing. This is because a frame can be covered up at any point by other windows, or because you minimise it, resize it, etc. In fact you don't necessarily need to handle a REdraw for all those cases, but you get the idea.
So, this is not the most efficient, because it performs a redraw regardless of the event, by responding to ANY paint event by drawing a line, but obviously that will do the job:
wxFrame:connect(Frame, paint, [{callback,
fun(_Evt, _Obj) ->
io:format("paint~n"),
DrawContext = wxPaintDC:new(Frame),
wxDC:drawLine(DrawContext, {50, 50}, {150,100}),
wxPaintDC:destroy(DrawContext)
end
}]).
I added the io:format in there so you can see that it is being called when you interact with the window, or some other window interacts with it, because without the io:format call it's a bit invisible in its effect, other than making sure there's always a line in your window.
I also used a draw context. I won't go into it here, I'm afraid it's just one of a load of things you need to learn about X Windows programming, but basically, just be aware for now, you need to have a draw context for your frame, and use that to actually draw with.
One last thing, you need to actually display the frame, if you want to see it, like this:
wxFrame:show(Frame).
Now you should see a window, with a line.

Michael's answer tells you how to do what you want to do, so let me address the confusion about the error
message.
In Erlang, functions that have the same name but different number of arguments are considered separate functions. The number of arguments is called the "arity", and is sometimes indicated as e.g. /2 after the function name.
Your code is calling wxDC:drawLine with two arguments, but you get an error saying that wxDC:drawLine/2 is undefined. In the documentation, you can see that the function you want is wxDC:drawLine/3, which takes three arguments (the first being the draw context, and the second and third being the points between which you want to draw a line).

Related

How can I get the CIAttributedTextGenerator filter to break onto multiple lines?

I'm working on an app that overlays text onto an image. We want to be able to constrain the width of the text and have it break onto multiple lines, much in the same way that UILabel does when we set numberOfLines = 0. In my mind, this should be possible by constraining the extent that the filter has to work within somehow, or by chaining it with a clamp (since the output bitmap is generated lazily.) Unfortunately, nothing I've run into seems to do the trick:
The CIClamp approach generates a nil outputImage when provided a CIVector(cgRect:) argument
There doesn't seem to be a way to specify a CIFilterShape to draw the text within when using the bundled filters
You can provide a CIFilterShape when invoking CIKernel.apply but a) I don't have a custom CIKernel (and am hoping not to write one) and b) I don't have a way to extract the kernel from the CIAttributedTextGenerator filter
I'm resigning myself to manually computing line breaks but it really seems like Core Image ought to be able to handle this use case. Am I just missing something?

Is it possible to simulate a erase action without having to create an extra shape in KonvaJS?

I am following this guide which contains a brush and eraser functionality. The guide's code sets the "globalCompositeOperation" to "destination-out" and basically ends up creating another line that will cover whatever you have drawn before with the brush.
This would work pretty well in some cases, but if I made my "destination-out" lines not-draggable and the "source-over" lines draggable, then if I drag the "source-over" lines around the canvas these lines would still be intact and it would not look like as if they were erased.
In a better attempt to explain my problem, I provide you this example: If I were to create two parallel lines, line1(x1,y1) and line2(x2,y2), and then I decide to draw a "destination-out" line in the middle of both, is there a way I can keep that "erased" part in the middle of line1 and line2 if I were to move one of the lines away from the "destination-out" line?
I'm sure it is not like this, but is it possible to change certain points inside the line as "destination-out" while the rest of the points are "source-over" If not, how can we simulate this action without having to create a long static extra "destination-out" line?

Lua Ti-nspire platform.window:invalidate()

I've searched many places for what platform.window:Invalidate() exactly does to the drawing screen on the Ti-Nspire, but sadly no in-depth answers come up.
Some sources say that by calling it 'invalidates' the window, or calls on.paint function. I don't exactly understand this, including why arguments can be included in the Invalidate(blah,blah2,blah3,blah4); does this mean that the on.paint function is called and can only repaint the portion defined, as if the other area not included in the argument is permanent?
I just found here that the on.paint gets 'flagged to fire' upon calling platform.window:Invalidate().
The entire window can be forced to repaint with by calling the function with no arguments : platform.window:invalidate()
If arguments are given, it will only be able to paint onto the area of x, y, width, height. The area outside of this outline is unaffected.

Find where on a path a touch is (by percentage)

I have a CGPath, and on that path I detect touches. The path is basically a line or a curve, but it is not filled. The idea is that the user strokes the path, so wherever the user has stroked along the path I'd like to draw the path with a different stroke/color etc.
First, to find if the touches are inside the path, and to give the user some room for error, I'm using CGPathCreateCopyByStrokingPath, and CGPointInsidePath. This works fine.
Next, I need to find how far along the path the user has stroked. That is today's question.
When that is done, and I have an answer like 33%, then I'd be a simple assignment to strokeEnd on the path. (two copies, one complete path, and one on top with strokeEnd set to whatever percentage of the complete path the user has stroked with his finger so far).
Any ideas how to find how far along the path the user has stroked his finger?
I have worked on this quite a while, and would like to share my answer (I'm the one who asked the question btw).
I want to detect touches along a path (e.g a Bezier Curve). Problem is that it can only tell you if a touch hit the path, but not where (using CGPathContainsPoint).
To avoid having the user hit exactly on the path, create a fatter version with CGPathCreateCopyByStrokingPath), so that's the one to check for touch on.
The main problem still is, where along the path did the touch hit. What I did was to create a dashed path copy with CGPathCreateCopyByDashingPath with minimal spacing. This path is never actually displayed. Then I got every part of it with the CGPathApply saving every path element in an array.
When a touch is detected, and is within the "fat path", then I just loop through the array of path-dash-elements, checking the distance (just regular Pythagoras) to the start-point of each path-dash-element.
If the touch-point is closest to the 14'th element, and there are e.g. 140 elements total, that means we're 10% along the way.
Now that we have the percentage. What I want now is to paint the path as far as the touch. I tried to use the suggested strokeEnd property on a path. That didn't match my calculated percentage at all. Actually, it seemed to me to be quite inaccurate. Or maybe my calculation is.
Anyway, since we already have all the path-elements, and know which one to stop at (the 14th element), what I did was to build a new path using the path-elements. Since I didn't want a dashed path (that was just a trick to find out where the touch was on the long continuous path), I just skipped all the moveTo path-elements (except the very first). That will create a continous path.
CGPathApply - by request
// MARK: - Stuff for CGPathApply
typealias MyPathApplier = #convention(block) (UnsafePointer<CGPathElement>) -> Void
// http://stackoverflow.com/questions/24274913/equivalent-of-or-alternative-to-cgpathapply-in-swift
// Note: You must declare MyPathApplier as #convention(block), because
// if you don't, you get "fatal error: can't unsafeBitCast between
// types of different sizes" at runtime, on Mac OS X at least.
func myPathApply(path: CGPath!, block: MyPathApplier) {
let callback: #convention(c) (UnsafeMutablePointer<Void>, UnsafePointer<CGPathElement>) -> Void = { (info, element) in
let block = unsafeBitCast(info, MyPathApplier.self)
block(element)
}
CGPathApply(path, unsafeBitCast(block, UnsafeMutablePointer<Void>.self), unsafeBitCast(callback, CGPathApplierFunction.self))
}
I have a utility class GHPathUtilies.m which includes a method:
+(CGFloat) totalLengthOfCGPath:(CGPathRef)pathRef
This is all written in Objective-C, but presumably you could use the same technique to walk along the path elements, using CGPathApply, until you are near enough, or have passed the target point. The general idea is to break the curves between each element into small line segments and keep a running sum of the length of each segment.
Of course if the path doubles back on itself, you'll have to figure out which point is the touch point.

Corona SDK dynamic width objects

I'm trying to implement a game mechanics of "Hooking" objects... Here's picture of what i'm talking about:
But I have a problem with the chain/string of the hook.
I've tried create it step by step when the hook is on the fly, using timer and enterFrame events, but they both generate huge gaps between chain segments.
I've tried creating big image of whole chain and changing width dynamicly, but it only stretches and looking funny :D
Maybe anyone faced the same problem?
I would suggest you to try following.
Create whole chain
place it inside container (display.newContainer)
change width of container.
Container automatically generates masks so instead of stretching you will have just part of your chain hidden under mask.
here is link to container docs http://docs.coronalabs.com/daily/guide/graphics/container.html
This is not a complete answer - I have given you a bit of a broad answer to a broad question but I hope it can help you in creating what you need.
I created a very similar mechanic recently -
I used enterFrame to call a function, lets call it BuildHook, this would check the position of the hook and the position of the starting point and then calculate how many pieces of images would be needed to fill out the space. The graphic I had as my "hook" was partially larger then the chain pieces allowing for it to overlap and only put a new image once enough space between the last piece and hook was created.
This ment that it was the hook moving forward and backwards and then having a static "chain" between it and the starting point. Either consuming "links" as would move backwards ontop of them or created "links" as it moved away from them.
Keep in mind this is pseudo code but should give you an idea how to make it.
local arrayOfPieces = {}
local function BuildHook()
-- Bunch of variables you need to get
startX,startY,
hookX,hookY,
lastPieceX,lastPieceY,
singlePieceWidth
-- The hook pseudo code
if(hookX - lastPieceX >= singlePieceWidth) then
local newPiece = display.newImage('singlePiece.png');
newPiece.x = lastPieceX + singlePieceWidth/2
newPiece.y = lastPieceY
table.insert(arrayOfPieces,newPiece)
end
if(hookX < lastPieceX) then
lastPieceArrayPos = table.getn(arrayOfPieces)
table.remove(arrayOfPieces,lastPieceArrayPos)
lastPiece = arrayOfPieces[lastPieceArrayPos - 1]
end
end

Resources