123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- # author: Ethosa
- ## It provides primitive display progress.
- import
- ../thirdparty/opengl,
- ../core/vector2,
- ../core/rect2,
- ../core/anchor,
- ../core/input,
- ../core/color,
- ../core/enums,
- ../nodes/node,
- ../nodes/canvas,
- ../graphics/drawable,
- control,
- math
- const CIRCLE_STEP: float = TAU * 0.01
- type
- ProgressBarType* {.pure.} = enum
- PROGRESS_BAR_HORIZONTAL,
- PROGRESS_BAR_VERTICAL,
- PROGRESS_BAR_CIRCLE
- ProgressBarObj* = object of ControlRef
- max_value*, value*: float
- progress_color*: ColorRef
- indeterminate_val*: float
- indeterminate*: bool
- progress_type*: ProgressBarType
- ProgressBarRef* = ref ProgressBarObj
- proc ProgressBar*(name: string = "ProgressBar"): ProgressBarRef =
- ## Creates a new ProgressBar.
- ##
- ## Arguments:
- ## - `name` is a node name.
- runnableExamples:
- var p = ProgressBar("ProgressBar")
- nodepattern(ProgressBarRef)
- controlpattern()
- result.value = 0
- result.max_value = 100
- result.progress_color = Color(0.6, 0.6, 0.6)
- result.rect_size.x = 120
- result.rect_size.y = 20
- result.indeterminate = false
- result.indeterminate_val = 0
- result.progress_type = PROGRESS_BAR_HORIZONTAL
- result.kind = PROGRESS_BAR_NODE
- method draw*(self: ProgressBarRef, w, h: GLfloat) =
- ## It uses for redraw ProgressBar.
- let
- x = -w/2 + self.global_position.x
- y = h/2 - self.global_position.y
- # draw progress
- let progress_percent = self.value / self.max_value
- case self.progress_type
- of PROGRESS_BAR_HORIZONTAL:
- procCall self.ControlRef.draw(w, h)
- glColor4f(self.progress_color.r, self.progress_color.g, self.progress_color.b, self.progress_color.a)
- let progress_width = progress_percent * self.rect_size.x
- if self.indeterminate:
- if self.indeterminate_val - progress_width < self.rect_size.x:
- self.indeterminate_val += self.rect_size.x * 0.01
- else:
- self.indeterminate_val = -progress_width
- glRectf(
- normalize(x + self.indeterminate_val, x, x + self.rect_size.x), y,
- normalize(x + self.indeterminate_val + progress_width, x, x + self.rect_size.x), y - self.rect_size.y)
- else:
- glRectf(x, y, x + progress_width, y - self.rect_size.y)
- of PROGRESS_BAR_VERTICAL:
- procCall self.ControlRef.draw(w, h)
- glColor4f(self.progress_color.r, self.progress_color.g, self.progress_color.b, self.progress_color.a)
- let progress_width = progress_percent * self.rect_size.y
- if self.indeterminate:
- if self.indeterminate_val - progress_width < self.rect_size.y:
- self.indeterminate_val += self.rect_size.y * 0.01
- else:
- self.indeterminate_val = -progress_width
- glRectf(
- x, normalize(y - self.indeterminate_val, y - self.rect_size.y, y),
- x + self.rect_size.x, normalize(y - self.indeterminate_val - progress_width, y - self.rect_size.y, y))
- else:
- glRectf(x, y, x + self.rect_size.x, y - progress_width)
- of PROGRESS_BAR_CIRCLE:
- self.CanvasRef.calcGlobalPosition()
- let
- progress_width = progress_percent * TAU
- cx = x + (self.rect_size.x / 2)
- cy = y - (self.rect_size.y / 2)
- orad = min(self.rect_size.x, self.rect_size.y) / 2
- irad = (min(self.rect_size.x, self.rect_size.y) / 2) - 5f
- # background:
- glColor4f(self.background.getColor().r, self.background.getColor().g, self.background.getColor().b, self.background.getColor().a)
- glBegin(GL_TRIANGLE_STRIP)
- for i in 0..90:
- let angle = TAU * (i/90)
- glVertex2f(cx + orad*cos(angle), cy - orad*sin(angle))
- glVertex2f(cx + irad*cos(angle), cy - irad*sin(angle))
- glEnd()
- # progress:
- glColor4f(self.progress_color.r, self.progress_color.g, self.progress_color.b, self.progress_color.a)
- if self.indeterminate:
- if self.indeterminate_val - progress_width < TAU:
- self.indeterminate_val += CIRCLE_STEP
- else:
- self.indeterminate_val = -progress_width
- glBegin(GL_TRIANGLE_STRIP)
- for i in 0..90:
- let angle = TAU * (i/90)
- if angle > self.indeterminate_val and angle < progress_width + self.indeterminate_val:
- glVertex2f(cx + orad*cos(angle), cy - orad*sin(angle))
- glVertex2f(cx + irad*cos(angle), cy - irad*sin(angle))
- glEnd()
- else:
- glBegin(GL_TRIANGLE_STRIP)
- for i in 0..90:
- let angle = TAU * (i/90)
- if angle < progress_width:
- glVertex2f(cx + orad*cos(angle), cy - orad*sin(angle))
- glVertex2f(cx + irad*cos(angle), cy - irad*sin(angle))
- glEnd()
- method duplicate*(self: ProgressBarRef): ProgressBarRef {.base.} =
- ## Duplicates ProgressBar object and create a new ProgressBar.
- self.deepCopy()
- method setMaxValue*(self: ProgressBarRef, value: float) {.base.} =
- ## Changes max value.
- if value > self.value:
- self.max_value = value
- else:
- self.max_value = self.value
- method setProgress*(self: ProgressBarRef, value: float) {.base.} =
- ## Changes progress.
- if value > self.max_value:
- self.value = self.max_value
- else:
- self.value = value
- method setProgressColor*(self: ProgressBarRef, color: ColorRef) {.base.} =
- ## Changes progress color.
- ## For change background color use `setBackgroundColor` method.
- self.progress_color = color
|