% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/paintr-app.R
\name{ptr_server}
\alias{ptr_server}
\title{Server for a \code{ggpaintr} Formula}
\usage{
ptr_server(
  formula,
  id = NULL,
  envir = parent.frame(),
  ...,
  shared_state = NULL,
  spec = NULL
)
}
\arguments{
\item{formula}{Either a single character scalar containing a ggplot
expression with \code{ggpaintr} placeholders, or an unquoted ggplot
expression supplied directly. See \code{\link[=ptr_app]{ptr_app()}} for the full contract
(expression capture via \code{\link[rlang:defusing-advanced]{rlang::enexpr()}}, symbol resolution,
wrapper unwrap, and the native-pipe caveat in expression mode).}

\item{id}{Optional module id; must match the id passed to \code{\link[=ptr_ui]{ptr_ui()}} or
to the bare L3 pieces. Defaults to \code{NULL} (identity namespace,
single-instance use).}

\item{envir}{Environment used to resolve local data objects.}

\item{...}{Forwarded to \code{\link[=ptr_init_state]{ptr_init_state()}}.}

\item{shared_state}{Optional \code{ptr_shared_state} returned by
\code{\link[=ptr_shared_server]{ptr_shared_server()}}. When supplied, populates \code{shared},
\code{draw_trigger}, and \code{shared_resolutions} defaults. Required when the
formula declares a \code{shared = "..."} placeholder driven by a
cross-formula \code{\link[=ptr_shared_panel]{ptr_shared_panel()}} and the equivalent \code{...} arguments
are not supplied directly.}

\item{spec}{An optional named list of fully-qualified Shiny input id ->
value, used to override widget defaults at session boot.}
}
\value{
The \code{ptr_state} list from \code{\link[=ptr_init_state]{ptr_init_state()}}. This is the
\strong{supported L3 custom-render handle}: \code{state$runtime()$plot} /
\verb{$code} / \verb{$error}. (Its \code{server_ns_fn} / \code{ui_ns_fn} slots are
internal plumbing — not a public escape hatch.)
}
\description{
The \strong{single public server-side entry point} for a \code{ggpaintr} formula,
used identically at L2 (default layout via \code{\link[=ptr_ui]{ptr_ui()}}) and L3 (your own
hand-composed layout from the bare \verb{ptr_ui_*} pieces). It namespaces and
wires the whole reactive engine, registers the built-in \code{ptr_plot} /
\code{ptr_error} / \code{ptr_code} outputs (a piece you never place in the UI is a
harmless no-op), and \strong{returns the \code{ptr_state}} so you can drive a
custom renderer. Additional arguments are forwarded to \code{\link[=ptr_init_state]{ptr_init_state()}}
(e.g. \code{shared}, \code{draw_trigger}, \code{expr_check}, \code{safe_to_remove},
\code{ui_text}).
}
\section{Custom render (L3)}{

Custom rendering is \strong{UI-side}: place your own output widget (e.g.
\code{plotly::plotlyOutput()}) at \code{shiny::NS(id)("my_plot")}, never place
\code{\link[=ptr_ui_plot]{ptr_ui_plot()}}, and read the live plot off the returned state — there
is \strong{no} user-authored \code{moduleServer} wrapping any ggpaintr engine and
\strong{no} lower-level server function to reach for:

\if{html}{\out{<div class="sourceCode">}}\preformatted{# server:
state <- ptr_server(formula, "p")
output$my_plot <- plotly::renderPlotly(state$runtime()$plot)
# ui: plotly::plotlyOutput(shiny::NS("p")("my_plot"))
}\if{html}{\out{</div>}}

\code{state$runtime()} is reactive; \verb{$plot} is the built ggplot/ggplot-like
object, \verb{$code} the generated source string, \verb{$error} any inline error.
See \code{vignette("ggpaintr-tutorial")}.

For cross-formula coordination — multiple ggpaintr instances driven by
one widget — build the coordinator with \code{\link[=ptr_shared_server]{ptr_shared_server()}} and pass
the returned \code{ptr_shared_state} as \verb{shared_state =}. The state's
\code{shared} / \code{draw_trigger} / \code{shared_resolutions} slots are unpacked and
forwarded to \code{\link[=ptr_init_state]{ptr_init_state()}}; if an explicit \code{shared = ...} /
\code{draw_trigger = ...} / \code{shared_resolutions = ...} is also passed via
\code{...}, that explicit value wins. A single formula with \code{shared = "..."}
placeholders needs no \code{shared_state} — \code{ptr_server()} self-binds every
declared key under its own namespace, matching what \code{\link[=ptr_app]{ptr_app()}} does.
}

\examples{
if (interactive()) {
  f <- rlang::expr(ggplot(mtcars, aes(x = ppVar, y = ppVar)) + geom_point())
  # L2: default layout
  shiny::shinyApp(
    ui = shiny::fluidPage(ptr_ui(!!f, "p")),
    server = function(input, output, session) {
      ptr_server(!!f, "p")
    }
  )
  # L3: own the render path off the returned state
  shiny::shinyApp(
    ui = ptr_ui_page(
      ptr_ui_controls(formula = !!f, id = "p"),
      plotly::plotlyOutput(shiny::NS("p")("my_plot"))
    ),
    server = function(input, output, session) {
      state <- ptr_server(!!f, "p")
      output[[shiny::NS("p")("my_plot")]] <-
        plotly::renderPlotly(state$runtime()$plot)
    }
  )
}
}
\seealso{
\code{\link[=ptr_ui]{ptr_ui()}}, \code{\link[=ptr_ui_plot]{ptr_ui_plot()}}, \code{\link[=ptr_shared]{ptr_shared()}},
\code{\link[=ptr_shared_panel]{ptr_shared_panel()}}, \code{\link[=ptr_shared_server]{ptr_shared_server()}}.
}
